Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

RXSwift

RxSwiftを試してみた。

CocoaPodでインストールした上で以下をインポート

import RxSwift
import RxCocoa

使い方は

        textFiled!.rx.text
            .map {
                guard let text = $0, text.lengthOfBytes(using:.utf16) > 0 else {
                    return ""
                }
                return "\(text)!"
            }
            .bindTo(label!.rx.text)
            .addDisposableTo(disposeBag)

これだけでラベルにテキストフィールドの値を加工したものが即時反映される。

継続モナド

継続モナドはSwiftで段階的に作れる。

1. まず継続渡しの関数を作る。

func getA(complete:(String)->Void) {
    complete("X")
}

2. 継続渡しの関数を引数にとるクラスを作る。

typealias Func<T> = (T)->Void

public struct RDFuture<T> {
    
    public var f:(Func<T>)->()
    
    public func result(_ complete:(T) -> Void) -> Void {
        f(complete)
    }
    
    init(_ f:@escaping (Func<T>)->()) {
        self.f = f
    }
}

これで骨組みはできた。

このように使う

func test() {
    let f = RDFuture(getA)
    
    f.result {
        print($0)
    }
}

これに、bind的な実装をつけることになる。

Realm

Realmを試してみた。便利だ。。

import Foundation
import RealmSwift

class Man : Object { // ObjectはRealmのクラス
    dynamic var name = "" // dynamicはobjective-Cのランタイムを利用して値にアクセスする
    dynamic var age = 10
    let cats = List<Cat>()  // ListはRealmのクラス
    
}

class Cat : Object {
    dynamic var name = ""
    let owners = LinkingObjects(fromType: Man.self, property: "cats")
}

class Test {
    func test() {
        let man = Man()
        man.name = "ho"
        man.age = 5
        
        
        let cat = Cat()
        cat.name = "mi"
        
        
        let realm = try! Realm()
        
        try! realm.write {
            realm.deleteAll()
            realm.add(man)
            realm.add(cat)
            let man = realm.objects(Man.self).filter("name == 'ho'").first!
            man.cats.append(cat)


        }
        

        
        let babies = realm.objects(Man.self).filter("age < 2")
        print("\(babies.count)")
        
        DispatchQueue(label: "background").async {
            autoreleasepool {
                let realm = try! Realm()
                let men = realm.objects(Man.self)
                let man = realm.objects(Man.self).filter("age == 5").first!
                try! realm.write {
                    man.age = 10
                }
                let cat = realm.objects(Cat.self).filter("name == 'mi'").first!
                
                print("\(man.cats.first?.name)")
                print("\(cat.owners.count)")

                let babies = realm.objects(Man.self).filter("age == 10")
                print("\(babies.count)")
                

            }
        }
    }
}

proxy

export USERNAME=
export PASSWORD=
export HOST=
export PORT=
export PROXY=$USERNAME:$PASSWORD@$HOST:$PORT
export http_proxy=http://$PROXY
export https_proxy=https://$PROXY
export ftp_proxy=ftp://$PROXY
export HTTP_PROXY=http://$PROXY
export HTTPS_PROXY=https://$PROXY
export FTP_PROXY=ftp://$PROXY
export no_proxy=
export NO_PROXY=$no_proxy

以下を参照した。
プロキシ下でLinuxを使う際のメモ - Λlisue's blog

viewWillLayoutSubviews

viewWillLayoutSubviewsはviewのlayoutSubviewsの前に呼ばれる。
ちなみにlayoutSubviewsはレイアウト更新タイミング、制約つけたいときはupdateConstraints。

viewWillLayoutSubviewsは結果的にViewWillAppearとViewWillDidAppearの中間で呼ばれることになる。

画面切替

snapshotViewとの組み合わせでいける。

          let currentView = self.view.snapshotView(afterScreenUpdates: true)!
          self.view.addSubview(currentView)
          UIView.transition(with: currentView, duration: 0.5, options: [.transitionFlipFromRight], animations: {
                currentView.frame = CGRect(origin: CGPoint(x:-self.view.frame.width, y:currentView.frame.origin.y), size: currentView.frame.size)
            } , completion: { _ in
                    currentView.removeFromSuperview()
            })

幾つかのメモ 2

ImageButtonはボタン背景がついてしまう。

画像つきボタンはImageViewを使えば良い。

文字付きアイコンはShapeを定義してバッググラウンドに指定する。

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
	<solid
		android:color="@color/hoge"/>
	<stroke
		android:width="1dp"
		android:color="@color/hoge2"
		/>
	<corners android:radius="3dp" />
</shape>

のようなものを作って、textViewのandroid:backgroundに指定すれば良い。

スタイル設定

共通のxmlの色や幅等を共通なものを指定したい場合styleを作りそれを指定するようにできる。

画像回転

		view.setRotation(-90F);

レイアウト関連

  1. Drawableフォルダには画材的なxmlを置く。
  2. dimensフォルダにはデバイスの大きさごとの指定を置く。
  3. FrameLayoutは何もしないレイアウト
  4. RelativeLayoutは何々は何々の上にあるとかを指定するレイアウト
  5. 絶対座標は使わないこと。
  6. データバインディングデータ バインディング ライブラリ | Android Developers

バインドの取得とセット

		binding = DataBindingUtil.bind(mView);
		binding.setHoge(mHoge);

Hogeのところはxmlのdataのnameによって自動的に作られる。bindingの型もdataに設定するtypeから作られる。

xmlはレイアウトを以下で包む必要がある。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="android.view.View"/>
        <variable name="hoge" type="jp.co.hoge.app.activity.hogeActivity.HogeItem" />
    </data>

バインドの指定は

    <TextView
        android:text='@{hoge.name, default=名前 }'
        />