2018年8月11日土曜日

Found an unexpected Mach-O header code: 0x72613c21

問題

Xcode9の画面。
以前のバージョンでも出てた模様。
正常に動いていたアプリをAppStoreに提出すべくArchiveをし、Validate...しようとしたら
Found an unexpected Mach-O header code: 0x72613c21
という妙ちきりんなメッセージが出てニッチもサッチも行かなくなった。

意味は

訳すと「予期しない Mach-O ヘッダーのコードを発見した」である。
Mach-O(マーク・オー)はmacOSの前身であるNESTSTEP由来のコンパイラが生成するオブジェクトファイル/実行ファイルのファイルフォーマットだそうだ。(カーネルの名前がMachだからだな)
さらにMachHeaderはCPUの種類、ファイルの種類などの情報が書かれたヘッダのようだ。
要するに想定外の 0x72613c21 という情報がヘッダに書かれてるということだろう。

メッセージで検索すると 0x72613c21 の部分も含めて全く同じものが出ているようだ。人によって数値が変わるわけじゃないのだな。

どうやらこれはFrameworkをインストールした際の設定などがうまくいってないっぽい。
自分の場合TwitterKitと、画像処理のためのオープンソースライブラリのOpenCVをインストールしているので、それが関係していそう。

対処

Logファイルを見ても、エラーメッセージの後にDVTFilePathがどうのというのがいくつも出ているけど、さっぱりわからなかった。

./Users/YourFile/Library/Developer/Xcode/DerivedData の削除をしてもダメ

XcodeでProductのClean、Clean Build Folder...をしてもダメ。

解決した

TwitterKitの公式サイトに書かれていたインストール方法が、以下のようだった。
  • TwitterKitをEmbedded Binariesに
  • TwitterKitとTwitterCoreをLinked Frameworks and Librariesに
TwitterKitが2つ出てきておかしいとは思いつつ、Embedded 〜 に追加すると自動的にLinked 〜 にも追加されるんで、下の方ではTwitterCoreしか追加してなかったのだが、それが良くなかったようだ。


結果的にEmbedded 〜 の方を削除し、Linked 〜 の方にだけあらためてTwitterKitを追加したところ、無事Validate...が通った。
Embedded 〜 に残しておいても通ったけど、Linked 〜 にTwitterKitが2つ重複して入るため、気持ち悪いから消した。

原因

こちら(stack overflow)の回答を見たところ、以下のような記述があった(英語で)。
Mach-O型のFrameworkが「Static(静的)ライブラリ」である場合、それをEmbed(埋め込み)フレームワークに入れるべきではありません。 Mach-Oタイプが「Dynamic(動的)ライブラリ」の場合は、Embedフレームワークに配置する必要があります。
TwitterKitがStatic LibraryなのかDynamic Libraryなのかよくわからんのだけど、結果的にEmbedded Binaries に入れず、Linked Frameworks 〜 に入れるべきだったのだな。

とにかく解決したようなので助かった。こんなん、ネットがなかったら絶対わからんかったもん。
今後やはりEmbedded 〜 にも入れないといけない不具合が出るかもしれないけど、そしたらまた追記/訂正します。

2018年8月10日金曜日

Twitter利用の新アプリ作成時、アカウント作成要に

TwitterのApplication Managementページに載ってたのを翻訳しとく。

2018年7月現在、新しいアプリを作成する前に、Twitterデベロッパーアカウントを申請して承認を受ける必要があります。 承認されると、developer.twitter.comから新しいアプリを作成することができます。
近い将来、apps.twitter.comで既存のアプリを引き続き管理できます。 しかし、すぐにこのサイトを廃止し、developer.twitter.comの開発者ポータルにすべての開発ツール、APIアクセス、およびアプリケーション管理を統合します。 このサイトをリタイアすると、そのポータルを介して既存のアプリケーションにアクセスして管理することができます。
既存のアプリはいいけど、次からはデベロッパーアカウントを作らないといけないようだ。めんどくせえ。
詳しくは新規アプリ作った時に追記する。

Twitterアプリがないと他のアプリからツイートできない?!

問題

TwitterKitでは、Twitter公式アプリをインストールしていないデバイスで、別のアプリからツイートを投稿しようとしても、以下のようなエラーを吐いて認証ができなくなってしまった。

2018-08-10 22:19:59.259526+0900 アプリ名[72348:10180750] [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}
2018-08-10 22:20:01.430469+0900 アプリ名[72348:10180372] [TwitterKit] Error obtaining user auth token.

たとえばXcodeのiPhoneシミュレータでテストしようとしても、いちいち公式アプリがないといけないことになる。

原因

これはツイッター社による仕様変更のためで、ここにあるように、以前はツイッターにアプリ登録の際、
https://example.com
ってごまかしていた Callback URL なるものをきちんと登録しないといけないという。

解決法

Callback URLってナニ? ってのが本音なのだが、時間がないので解決法方だけ記す。
TwitterKitを使用する際にTwitterのApplication Managementサイトでアプリの登録を行ったわけだが、新規登録の際に得られたConsumer Key (API Key) を使った擬似的なURLを書けばOKだ。



Consumer Keyが ABCDEFGHIJK だとすれば、Settingsタブで
https://example.com
のかわりに
twitterkit-ABCDEFGHIJK://
と書けばいい。
そして下のUpdate Settingsボタンを押して完了。
これですぐにアプリから認証ができるようになる。
簡単だけどめんどくさいな。

参考サイト:TwitterがインストールされていないとTwitterKitで認証できない

2018年8月4日土曜日

TwitterKitが変更された

気づいたらTwitterKitが3.4.0にアップデートされていた。公式サイト
^ <>\|`など、一部の文字がツイートできない問題も解決しているらしいので、さっそくインストールした。(後述するが、\ (バックスラッシュ)だけはいまだツイートできなかった)

Frameworkをインストール



公式サイトに書かれた通りにやる。
  1. TwitterKit.frameworkをEmbedded Binariesに追加
  2. TwitterKit.frameworkとTwitterCore.frameworkをLinked Frameworks and Librariesに追加
とある。
しかし1.ですでにTwitterKit.frameworkはLinked Frameworks and Librariesにも自動で追加されるているので、TwitterCore.frameworkだけでいいと思われる……と思ってあらためてLinked 〜 に追加しなかったところ、AppStoreに提出する前のValidate...時に以下のエラーが出て悩むことになった。
1.のEmbedded 〜 への追加はしてもしなくても良くて、2.のLinked 〜 にTwitterKitを追加してやったら直った。注意が必要だ。

TwitterKitResources.bundleも必要



公式サイトに書かれてないけど、TwitterKitのフォルダに入ってるTwitterKitResources.bundleというエイリアスファイルもそのままAdd Files to プロジェクト名 してやらないといけない。

bridging headerが必要

これまではSwiftではふつーに
import TwitterKit
としておけば良かったが、Objective-C用しか用意されていないらしく、Objective-C bridging headerを作らねばいけなくなった。
作り方はObjective-CとSwiftのコードを混在させる方法を調べてもらうとして、その中で
#import <TwitterKit/TWTRKit.h>
としなければならない。

Twitter --> TWTRTwitterに書き換える

Twitter.sharedInstance().application(app, open: url, options: options)
などと書いていたののTwitterの部分をTWTRTwitterと書き換える必要がある。
まあこれは簡単。

Linker Errorが出る


ここまでで完璧と思ってさっそくビルドしてみたところ、Apple Mach-O Linker (ld) Errorなどというエラーが出てしまった。
必要なFrameworkがインストールされていないか、必要ファイルへのpathが狂っているなどの場合に出るらしい。

MKMapViewとかMKMapView、_kUTTypeImageなどというメッセージからMapKit.frameworkとMobileCoreServices.frameworkが必要と判断して追加したら消えてくれた。
そんなことどこに書かれてんだよ。ツイッター、この野郎。

とりあえずビルドできるようになったのは幸い。

バックスラッシュだけはまだ送信できない

上述の通り、^ < >など一部の文字が含まれているとツイートできない問題は直っていたが、\(バックスラッシュ)だけはいまだツイートできなかった。
\(^o^)/ などというように顔文字で使われることがあるから早く直してくれないと困るな。制御文字を扱う際のprefixに使われてるせいじゃないかと思うが、ツイッター公式アプリやWeb版のツイッターじゃ問題ないんだからツイッター社の怠慢。