ObjecTips

Swift & Objective-C で iOS とか macOS とか

iOS 8.3 to iOS 9.0 API Differences ネットワークとWeb周り

結構 diffs の量が多いので分割分割で今回はネットワークとWeb周りについて。

関連記事は以下
iOS 8.3 to iOS 9.0 API Differences Core Image - ObjecTips
iOS 8.3 to iOS 9.0 API Differences オーディオ周り - ObjecTips
iOS 8.3 to iOS 9.0 API Differences ネットワークとWeb周り - ObjecTips
iOS 8.3 to iOS 9.0 API Differences CoreLocation - ObjecTips
iOS 8.3 to iOS 9.0 API Differences CoreTelephony - ObjecTips

CFNetwork

CFFTPStream, CFHTTPStream

HTTPとFTPのStream系の関数がまとめて deprecated になった。
新しく NSURLSessionStreamTask というのが登場したのでこれを使う。

CFSocketStream

kCFStreamNetworkServiceTypeVoIP
SocketStream自体は使えるけどVoIPだけ deprecated
VoIPを使いたい場合は PushKit を使えとヘッダに書いてあった。

CFHTTPMessage

kCFHTTPVersion2_0
HTTP 2.0 をサポート

Foundation

NSURLConnection

NSURLConnection を生成する系のメソッドが全て deprecated
事実上クラス自体が deprecated なので NSURLSession に移行する必要がある。

NSHTTPCookieStorage
+ (NSHTTPCookieStorage *)sharedCookieStorageForGroupContainerIdentifier:(NSString *)identifier NS_AVAILABLE(10_11, 9_0);

クッキーを App Groups のコンテナを通して Extension と共有できるようになった!これはありがたい。

NSURLSessionStreamTask

NSURLSessionTask のサブクラスでStream接続を行う Task で Read/Write どちらでも利用可能

- (void)captureStreams;

メソッドを呼ぶと接続が終了して、delegate メソッド

- (void)URLSession:(NSURLSession *)session streamTask:(NSURLSessionStreamTask *)streamTask
                                 didBecomeInputStream:(NSInputStream *)inputStream
                                         outputStream:(NSOutputStream *)outputStream;

が呼ばれる。
ここで close された状態の NSInputStreamNSOutputStream が取得できる。

NetworkExtension

VPNのトンネリングを行える Packet Tunnel Provider
プロキシ接続を行える App Proxy Provider
コンテンツをフィルタリングする Filter Data Provider と Filter Control Provider

この Extension を使えばプロキシ使って AdBlock する Extension とか作れちゃうんじゃないの?ヤバくない?
と思ったら

Each of the network extension points requires special permission from Apple.

との事でどうやら企業ユースらしい。良かった。
あれ、でも Xcode 7 から developer program 無しで実機インストールできるようになったよな。Extension のソース配布されちゃったらどうなるんだろ。
もしかして CarPlay の開発並みにちゃんと手続き踏まないと試しに作る事すらできないようになっているんだろうか。

SafariServices

SFContentBlockerManager

ドキュメントが無い上、ヘッダに一切コメントが無いので詳細は分からない。 用意されているメソッドは以下のみ

+ (void)reloadContentBlockerWithIdentifier:(NSString *)identifier completionHandler:(void (^__nullable)(NSError *__nullable error))completionHandler;

このメソッドから察するに、MDM のプロファイルでのコンテンツフィルタを使用する際のプラグインモードと関係あるかな?
プラグインの identifier を設定するとそのフィルタが読み込まれるとか?
詳細は Session を見るしかない。

f:id:Koze:20150611221907p:plain

SFSafariViewController

Safari ライクな画面を表示する ViewController で AutoFill や Safari Reader など Safari と同じ機能の多くが搭載されている。
クッキーとその他ウェブサイトのデータは Safari と共用される。 アプリ内でWeb表示を行う際にWebのコンテンツをカスタマイズしない場合は UIWebView WKWebView から SFSafariViewController へのリプレイスを検討せよとの事。

Safari とのクッキーの共有の機能が気になったけど SFSafariViewController は単機能でAPIからはWebコンテンツを表示して閉じるぐらいの事しかできないので、アプリが勝手にユーザの Safari のクッキー情報を取得する事はできなさそう。

WebKit

WKWebView
@property (nullable, nonatomic, copy) NSString *customUserAgent NS_AVAILABLE(10_11, 9_0);

トリッキーな事をしなくても普通に UserAgent を変更できるようになってる。素敵過ぎる。

WKWebViewConfiguration
@property (nullable, nonatomic, copy) NSString *applicationNameForUserAgent NS_AVAILABLE(10_11, 9_0);

UserAgent の一部だけをカスタマイズする方法も用意された。
詳しくは以下

WKWebsiteDataRecord, WKWebsiteDataStore

WKWebsiteDataStore で クッキー、ディスクキャッシュ、IndexedDBのDB、ローカルストレージ、メモリキャッシュ、オフラインWebアプリのキャッシュ、WebSQLのDBのデータを取得したり削除したりできる。
取得されるデータが WKWebsiteDataRecord クラスになっていて、このクラスで表示できるのはデータの種類と名前(主にドメイン名)のみ。
データの中身を編集する事はできない。

使い方はたぶんこんな感じ

データストアの生成には以下の2種類のクラスメソッドがあって

+ (WKWebsiteDataStore *)defaultDataStore;
+ (WKWebsiteDataStore *)nonPersistentDataStore;

後者のメソッドで生成したデータストアはシステムにデータを書き込まないのでプライベートブラウジングを実装するのに役立つとヘッダに書いてある。