2016年11月14日月曜日

UNNotificationAttachment.init(identifier: String, url: URL, options: [AnyHashable : Any]? = nil)に拡張子のないURLを渡す際の注意

iOS 10で導入されたUserNotifications.frameworkは大変便利ですが、落とし穴が早速幾つか見つかっておりますのでご紹介いたします。
参考: iOS 10で画像つきのNotificationを配信する - Qiita

表題にありますUNNotificationAttachment.init(identifier: String, url: URL, options: [AnyHashable : Any]? = nil)ですが、第二引数のurlに画像や動画などのメディアのURLを渡してUNNotificationContentに付与すると言う使い方をするのが一般的かと思います。

このときどうやらUserNotifications.frameworkはurlのpathExtension、要するに拡張子の情報を利用してメディアの種類を判別しているようで、以下のような状況が発生すると実機でのみUNNotificationAttachment.initの実行が失敗してnilが返却されます。

  • 第二引数のurlに拡張子が付与されておらず、かつoptionsに[UNNotificationAttachmentOptionsTypeHintKey: "<当該URLのメディアの適切なMIME Typeを表す文字列>"]が指定されていない場合。
  • または間違った拡張子やMIME Typeが指定されている場合。

なおシミュレータでは問題ありません。いきなり実機に持っていって困るということが有るかと思いますので十分ご注意ください。

対処法は2つあります。

  1. URLに適切な拡張子を付与する
  2. optionsに[UNNotificationAttachmentOptionsTypeHintKey: "<当該URLのメディアの適切なMIME Typeを表す文字列>"]を付与する

何れにせよURLが指し示すメディアの種類が正確にわかっていないと問題になるため、その点は注意が必要です。

2016年10月4日火曜日

Q. ATS を Debug ビルドでだけ無効にしたいのですが...

A. こちらの内容に従えば一発です。

要するにBuild Phaseにビルドスクリプトを追加してそこでPlistBuddyを使って値を書き換えましょうと言う作戦です。

もうちょっとマシな解説

普段、Info.plistの設定内容をConfiguration毎に書き換えたい場合は、たいていよくやるのがxcconfigファイルを以下のように用意して、
APP_BUNDLE_NAME = MyApp_Dev
でもってInfo.plistに対して
Bundle Display Name = ${APP_BUNDLE_NAME}
こんな風に書いておけばビルド時に自動的にXcodeが環境変数による置換処理を行ってくれる、というのを使うのですが、まいったことにATSの設定を司るNSAllowArbitraryLoadsはString値ではなくBool値でして、このInfo.plistに対するXcodeの環境変数置換処理はString値(と、確かNumber値)にしか使えないというオチがあります。仕方がないので最初に説明した方法が最善になるかと思います。Info.plistファイルをConfiguration毎に用意する方法もありますが、大概そっちのほうが設定のメンテナンスが面倒になるのでオススメしません。

2016年10月3日月曜日

ATS の AVFoundationに対する 例外条項の注意点

2016/10/03段階でのATSを有効にする際の覚書です。基本的には全てTLS 1.2以上をサポートするhttpsにしてしまえばOKですが、例外条項としてAVFoundationのStreamについてはhttpでもよいと例外条項が定められています。

https://developer.apple.com/videos/play/wwdc2016/706/?time=324

これについては設定不要で自動的に適用されるようにWWDCのビデオ上では見えますが、実は落とし穴があり、この例外条項はiOS 10以降でのみしか適用されません。iOS 9については実はAVFoundationのStreamについてATSが完全に適用されているようで、httpの動画をStreamingしようとしても失敗してしまうので注意が必要です。

2016/10/03 16:45 追記
こちらXcode 7.3.1でビルドしたバイナリにて調査した内容ですので、SDKのバージョンが異なるXcode 8.0以降でビルドしたバイナリであればiOS 9.x系でもAVFoundationのStreamについてATSの例外条項が適用されてhttpで通信できるようになるかもしれません。ただ紹介した参照元のWWDCのビデオを見ても分かる通り、基本は例外を考えず全てhttps化するのが良いとされているため、ビデオストリームについても可能であれば全てhttps化するほうがトラブルがないかと思います。