面白きことは良きことなり

拙く未熟なiOSエンジニアの備忘録と戯言

UIColorの比較で単純に==や!=してはいけない話(Swift3コード追記)

UIColorの比較の注意点

UIColor同士を比較する際、==!=で比較することは可能。 しかし、安易にこの比較を行なった場合、意図しない挙動になることもある。

その例が下記となる f:id:aryzae:20170520162714p:plain

UIColorの作成時、white値を指定して作成することもできれば、rgba値を指定して作成することもできる。 この作成の仕方で、同じ色でも比較時にfalseが返る。

Objective-Cの時、UIColor.whiteUIColor(white: 1, alpha: 1) で作成したインスタンスは同じアドレスを挿していた。そのため、== の比較でも同じオブジェクトを指していたのでtrueになるのは当然だった。

Swift3で同じ様にアドレスを確認すると、別のアドレスを指しているのが画像からわかる。つまり別オブジェクトでも同一とのものと判定されていることがわかる。

同じ色でもfalseが返る理由

では、なぜ同じ色なのに比較するとfalseが返るか。 それはdumpで見るとわかる。

f:id:aryzae:20170520165104p:plain

このように同じ色でも、インスタンスの生成の仕方で継承しているクラスが異なっているためである。

生成方法に左右されない比較方法

生成方法が異なっていても、楽に比較するため==で比較できるようにメソッドを 書くのが良さそう。

// Swift3
func ==(lhs: UIColor, rhs: UIColor) -> Bool {
    var lhsRed: CGFloat = 0.0
    var lhsGreen: CGFloat = 0.0
    var lhsBlue: CGFloat = 0.0
    var lhsAlpha: CGFloat = 0.0
    lhs.getRed(&lhsRed, green: &lhsGreen, blue: &lhsBlue, alpha: &lhsAlpha)

    var rhsRed: CGFloat = 0.0
    var rhsGreen: CGFloat = 0.0
    var rhsBlue: CGFloat = 0.0
    var rhsAlpha: CGFloat = 0.0
    rhs.getRed(&rhsRed, green: &rhsGreen, blue: &rhsBlue, alpha: &rhsAlpha)

    return lhsRed == rhsRed && lhsGreen == rhsGreen && lhsBlue == rhsBlue && lhsAlpha == rhsAlpha
}

参考: UIColor の比較時の注意点 - Qiita

これで==で比較できるようになった。

f:id:aryzae:20170520170915p:plain


別案として、規約で縛る代わり==!=を許可するのも手だと思う。

具体的に言うと、下記を守れば==!=で比較しても正しく判定できる

  • UIColor生成時、rgbaを指定して作成する
  • UIColorが持つredColorやwhiteColorは使用しない

読みたいまたは購入予定本

モバイルアプリ開発エキスパート養成読本 (Software Design plus)

モバイルアプリ開発エキスパート養成読本 (Software Design plus)

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

詳解Swift 第3版

詳解Swift 第3版

Rxswift: Reactive Programming with Swift

Rxswift: Reactive Programming with Swift

軽量・高速モバイルデータベースRealm入門

軽量・高速モバイルデータベースRealm入門

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

プログラミングの基礎 (Computer Science Library)

プログラミングの基礎 (Computer Science Library)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

UIデザイナーのための Sketch入門&実践ガイド

UIデザイナーのための Sketch入門&実践ガイド

Kotlinスタートブック

Kotlinスタートブック

Xcodeでファイル配置を変更した際に出るWarningの対処方法

Missing file (〜 is missing from working copy)

  • gitで該当ファイルをコミットする

Dependency Analysis Warning

  • XcodeのUtilities(右カラム)>File inspectorのTarget Membershipからチェックを外す

or

  • ProjectのTargets>Build Phases>Copy Bundle Resourcesから該当ファイルを消す

Library not loadedでCrashした時に行なった対処

Library not loadedでクラッシュとの遭遇

アプリを作っている時は、問題なく実機で実行できていたが、 iTunes ConnectにバイナリのUploadが終わって、メタデータ用のスクリーンショットを撮ろうとシミュレータで実行した際に下記内容のクラッシュに初遭遇した。

dyld: Library not loaded: @rpath/Realm.framework/Realm
Referenced from: /var/containers/Bundle/Application/...
Reason: image not found

1. Embedded Binariesに追加とその結果

stackoverflow.com

  • Embedded BinariesにDynamic Libraryを入れる

→ 確かにクラッシュはしなくなる。動作も問題ない。 しかし、ArchiveしてiTunes ConnectにUploadする時、ValidateでErrorが発生する 内容は、Realm.frameworkにx86_64, i386のarchitectureは含まれていない。と。 ただ実行したいだけであればいいが、今回はStore申請も絡んでいるので却下。

2. 重複しているFrameworkの削除とその結果

uchinoinu.hatenablog.jp

  • 1.の対処を行なった結果、"Linked Frameworks and Libraries" に同名のframeworkが存在していたの削除

→ 結果変わらずクラッシュするまま。

3. Carthageの再updateと"Run script…“のチェックボックスを外す

  • 直前問題を起こしていそうな操作を思い出した結果、Carthage自体を0.22へversion upさせていた

    • ひとまずCarthageフォルダ直下にあるBuildフォルダを削除。 その後、carthage updateで再度Build以下を作り、"Linked Frameworks and Libraries"へ入れ直してあげた。
  • Firebase Crashを使うことで、何故かArchive時に200個以上んwarningが発生。 これの解消方法を探っている時、"Build Phases">“Run Script”>“Run script only when installing"にチェックを入れると解消されるとあり、試したままにしていた。(大量のwarning自体は解消できていない)

→ 実機実行してもクラッシュせず、Archive後のValidateでもSuccess!! 結局2つのうちどっちが効果あったかは不明だが、"Run script only when installing"が濃厚。 時間がないとはいえ、よくわからないオプションを見よう見まねでつけるのは危険

FirebaseをPodsを使わず直に取り込む際、DLするVersionに注意

前提

  • CocoaPodsを使わない
  • Firebaseを直にプロジェクトに取り込む

リンクが古い

前提に該当する人は、下記のリンクからzipファイルをDLする人が大半だと思う。 しかし、リンクを見るとFirebaseのバージョンが3.11となっている f:id:aryzae:20170506204238p:plain

ここで今最新のFirebaseがいくつかRelease Noteを確認すると・・・ f:id:aryzae:20170506204536p:plain

このように、細かくサイトはメンテナンスされているわけではないようである。

最新版のURL

最新版を取得するには、ひとまず下記のようにしたらDL可能だった。

https://dl.google.com/firebase/sdk/ios/3_11_0/Firebase-3.11.0.zip?hl=ja

https://dl.google.com/firebase/sdk/ios/3_17_0/Firebase-3.17.0.zip?hl=ja