カテゴリーアーカイブ Swift

村上 著者:村上

【Swift】KVO(Key-Value Observing)を触ってみた

昔他の人が開発したiOSアプリを修正していたのですが、現行の環境で実行したところエラーが発生しました。
で、エラー発生個所が KVO の処理のところだったので、修正もかねてちょっと触ってみました。
ちなみに、エラー修正前のアプリは、実行した直後に落ちました。

KVO について参考にさせていただいた記事はこちら。

Swift4のKVOに感動した。 – Qiita
https://qiita.com/ObuchiYuki/items/d00ce5f44725672184da

なお、KVO とは、オブジェクトの値の変更の監視をしてくれる Swift の機能です。

 

コードの修正ですが、下記の場所を修正しました。

func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutableRawPointer) {
    // 実行したい処理
}

こちらは、監視しているオブジェクトの値が変更されたら呼び出される関数なのですが、override しているわけではなかったので、これが怪しいのでは…?と思ったんですよね。
実際、KVO の処理をまるっとコメントアウトしてみたら、アプリは落ちることもなく動作したので、怪しいのはこのあたりのはず。

で、こちらを下記のように書き直しました。

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    // 実行したい処理
}

念のため、Xcode の関数補完機能を使ったので、問題はないはず。
若干、ここ以外にもコードの修正は必要でしたが、こちらを修正したところ、アプリが落ちることなく、問題なく実行できました。

とりあえず動くようにはなったので、今後は、時間があれば実際にここの処理が具体的に何をしているのかをみてみたいと思います。

 

以上、Swift の KVO 機能を修正してみた、でした。
参考になれば嬉しいです。

  • この記事いいね! (0)
村上 著者:村上

【Xcode】「Command PhaseScriptExecution failed with a nonzero exit code」エラーの対処法【未解決】

今回は Xcode でプロジェクトをビルドした際に発生したエラーについて。
タイトルに書いてある通り、未解決なのですが、いくつか参考になりそうな記事は見つかったので、とりあえずそれをまとめました。
今後解決できたら、改めてその手順についてまとめる予定です。

 

エラーは「Command PhaseScriptExecution failed with a nonzero exit code」というもの。
翻訳すると、「コマンドPhaseScriptExecutionがゼロ以外の終了コードで失敗しました」とのことですが…これだけでは意味不明です…。

で、解決策ですが、参考になりそうだったのがこちらの2つ。

[Swift, Xcode] Command PhaseScriptExecution failed with a nonzero exit code – Qiita
https://qiita.com/kamata1729/items/885ae2cf2a9b06594adf

Command PhaseScriptExecution failed with a nonzero exit codeとの戦い – Qiita
https://qiita.com/masa-321/items/19f66557dcff65553f18

解決方法として共通しているのは、下の二つでした。

  1. キーチェーンアクセスを起動し、ロック→解除を実行後、アプリを再ビルド
  2. Pod を一度クリーン後、再インストール

ただ、こちらを実行しても、私の環境では解決できませんでした…。
アプリのクリーン→再ビルドも行ってみましたが、こちらも効果なし。
…もう少し、調査します。

 

以上、Xcode で発生したエラー「Command PhaseScriptExecution failed with a nonzero exit code」の対処法でした。
私は上記の方法では解決できませんでしたが…参考になれば幸いです。

  • この記事いいね! (0)
村上 著者:村上

【Swift】「Unexpectedly found nil while unwrapping an Optional value」エラーの対処法

最近、iOSアプリ開発に関する記事ばかりですが…今日も今日とて、アプリ開発中に遭遇したエラーについてです。

エラー文はこちら。

Unexpectedly found nil while unwrapping an Optional value

Google翻訳を使って翻訳したところ、「オプショナル値をアンラッピングしている間に予期せずnilが見つかりました」とのこと。
ある程度アプリ開発をしている人なら原因はすぐに分かるか、もしくはそもそもこのエラーが発生しないように対処済みかと思います。
が、Swift 初心者だと、オプショナル型が理解しづらく(実体験)、なかなかハマったのでまとめます。

 

今回参考にさせていただいたサイトはこちらから。

どこよりも分かりやすいSwiftの”?”と”!” – Qiita
https://qiita.com/maiki055/items/b24378a3707bd35a31a8

まずオプショナル型がイマイチわからない…という人は、この記事よりもこのリンクを読みましょう。

 

さて、対処方法ですが、まずエラーが発生したコードがこちら。

var title: Sting! // オプショナル型

/* 何らかの処理 */

print(title!);

簡単に説明すると、上記のコードの title という変数は、nil(null)を代入できるオプショナル型です。
非オプショナル型と違い、代入された値がラップ(包み紙)に包まれています。
これのおかげで、nil を扱うことができています。
で、この変数にタイトルのテキストを代入するなどの処理を行い、結果を print() で出力しています。
が、このとき、何らかの原因で、title変数に値が代入されないことがあります。
そして、中身が nil の状態で、包み紙を剥がすアンラップの処理を行うと、エラーが発生します。
このエラーが、今回紹介した「Unexpectedly found nil while unwrapping an Optional value」です。

これを解決するために、アンラップの処理を下記のように変更します。

// 変更前
// print(title!);

// 変更後
if let unwrap_title = title {
    print(unwrap_title)
}
else {
    print("値が代入されていません")
}

なお、この方法を「オプショナルバインディング」と言います。

簡単に解説すると、新しいコードでは、まずオプショナル型の変数を if 文以降の定数に代入しています。
その結果が nil でなかれば、if 以下の処理が実行されます。
一方で、title を代入した定数が nil であれば、else 以下の処理が実行されます。
なお、title の値は unwrap_title に代入されていますので、こちらを利用します。
処理としては以上です。

 

最初に紹介したアンラップ方法は、「強制的アンラップ」といい、文字通り代入された値に関係なくアンラップの処理を行います。
この方法は、絶対に nil が代入されない変数に対してのみ使うようにしてください。
そうでなければ、オプショナルバインディングを使うことを強く推奨します。

私も最初はオプショナル型が全く理解できず、かなり苦労しました。
個人的には、実際にコードを書いてみて、どういうときにプログラムが落ちるのかを体験するとわかりやすいかなと思います。

  • この記事いいね! (1)
村上 著者:村上

【Xcode】Type ‘UISlider’ does not conform to protocol ‘ValidatableInterfaceElement’エラーへの対処法

久しぶりに遭遇したXcodeでのエラーです。
特に内容を変更した記憶のないアプリを開いてみたら、いきなりビルドエラーが発生しました。
エラー分は下記のとおりです。

Type 'UISlider' does not conform to protocol 'ValidatableInterfaceElement'

どうやら、CocoaPodでインストールした「Validator」というライブラリ内部でエラーが発生していたことまでは突き止めたのですが、その原因がわからず…検索してもヒットしない状況でした。
なお、Validator についてはこちらから。

GitHub – adamwaite/Validator
https://github.com/adamwaite/Validator

が、会社にあるもう一台のMacbookでは問題なく動いていたので、そこが謎でした。

 

で、色々見てみた結果、どうやらXCodeのバージョンが影響していたことが判明!
先日、Xcode をアップデートして 9.3 にしたのですが、これを 9.2 に戻したら問題なく動き、ビルドも完了しました。
……Xcodeは不用意にアップデートしてはだめですね…。

なお、Xcodeの以前のバージョンをインストールする方法は、下記の記事を参考にしました。

Xcodeの旧バージョンをインストールする方法 – Qiita
https://qiita.com/TsukasaHasegawa/items/0d7d5c2cf3a2b8ce8993

ただ、ダウンロードに凄く時間がかかったので、何か別の作業をしながらのんびり待つことをおすすめします。
ダウンロード時間が「残り約60分」の表示を見た時は、正直ため息を付きそうになりました…。

 

ということで、ビルドエラーの解消方法でした。
同僚に聞いたところ、Xcode のバージョンの違いのせいで発生するバグってあるようなので、バグの原因が分からないときに確認するようにしましょう。

  • この記事いいね! (0)
村上 著者:村上

【未解決】Xcode 9.1 で ‘Cordova/CDVViewController.h’ file not found というエラーが発生

Cordova で開発中のアプリをビルドしようとしたところ、下記のようなエラーが発生しました。

MainViewController.h:28:9: ‘Cordova/CDVViewController.h’ file not found

エラー内容は書いてある通りで、MainViewController.h というファイルで、Cordova/CDVViewController.h が見つからないというものでした。
MainViewController.h を確認してみると、確かに #import <Cordova/CDVViewController.h> の行でエラーとなっていました。

 

解決方法を調べたところ、下記の画像のように、Build SettingsHeader Search Path の値に下記のような記述があるので、

"$(OBJROOT)/UninstalledProducts/include"

こちらを、

"$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include"

上記に変更すれば、実行できますとの書き込みを見つけたので、早速試してみました。

が、今回のエラーはこちらでは解決できませんでした…!
以前も全く同じエラーに遭遇したことがあり、その時はこのやり方で解決できたのですが、今回は何故かダメでした。
他にも、iOSのプラットフォームを一度削除した後、再度追加するとビルドできるとの記載もあったのですが、こちらも効果なし…。
それ以外の解決方法も検索してはいるのですが、ほぼ Build Settings > Header Search Path の値を修正するという解決策しかヒットしないので、正直手詰まりです。

もし、上記以外の解決策をご存知の方は、是非ともご教授くださいませ。
どうぞよろしくお願い致します。

  • この記事いいね! (4)