有時候需要在App內部打開一個網頁,例如為了展示公司官網,產品列表信息,Facebook,微博等。以前都是使用 UIWebView,iOS 8引入了WKWebView。但他們都存在各自的一些問題。
UIWebView:
- 始祖級別,支持的iOS版本比較多
- 可支持打開URL,包括各種URL模式,例如 Https,FTP等
- 可支持打開各種不同文件格式,例如 txt,docx,ppt,,音視頻文件等,很多文檔閱讀器會經常使用這個特性,感興趣的可以查一下Apple的文檔,支持的格式還是挺多,只是不同iOS 版本的支持程度不太一樣,使用時請多留意測試確認~
- 占用內存比較多,尤其是網頁中包含比較多CSS+DIV之類內容時,很容易出現內存警告(Memory Warning)
- 效率低,不靈活,尤其是和 JavaScript交互時
- 無法清除本地存儲數據(Local Storage)
- 代理(delegate)之間的回調比較麻煩,提供的內容比較低級,尤其是UI部分。如果想自己定制一個類似 Safari 的內嵌瀏覽器(Browser),那就坑爹無極限了,例如我們PDF Reader系列中的內嵌Browser,自己手動模擬實現Tab切換,底部Tool及各種Menu等,說多了都是淚~~
WKWebView:
- iOS 8引入的,比較年輕
- 在內存和執行效率上要比UIWebView高很多
- 開放度較高但據說Bug成噸
- 類似UIWebView,UI定制比較麻煩···
- 沒具體測試使用過,就不繼續列舉了 L~
好,終於輪到今天的主人公了,SFSafariViewController:
- iOS 9引入,更加年輕,意味着是Apple的新菜,總是有什么優勢的
- 也是用來顯示網頁內容的
- 這是一個特殊的View Controller,而不是一個單獨的 View,和前面兩個的區別
- 在當前App中使用Safari的UI框架展現Web內容,包括相同的地址欄,工具欄等,類似一個內置於App的小型Safari
- 共享Safari的一些便利特性,包括:相似的用戶體驗,和Safari共享Cookie,iCloud Web表單數據,密碼、證書自動填充,Safari閱讀器(Safari Reader)
- 可定制性比較差,甚至連地址欄都是不可編輯的,只能在init的時候,傳入一個URL來指定網頁的地址
只能用來展示單個頁面,並且有一個完成按鈕用來退出
圖1 SFSafariViewController演示截圖
如果你的App需要顯示網頁,但是又不想自己去定制瀏覽器界面的話,可以考慮用SFSafariViewController來試試。從好的方面看,SFSafariViewController也去掉了從App中跳轉到Safari的撕裂感,不同App之間切換總是讓人感覺麻煩和不舒服。
代碼例子:
- (IBAction)onButtonClick:(id)sender
{
NSString *urlString = @"http://www.kdanmobile.com";
SFSafariViewController *sfViewControllr = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:urlString]];
sfViewControllr.delegate = self;
[self presentViewController:sfViewControllr animated:YES completion:^{
//...
}];
}
// Done 按鈕
- (void)safariViewControllerDidFinish:(nonnull SFSafariViewController *)controller
{
[controller dismissViewControllerAnimated:YES completion:nil];
}
SFSafariViewController 的接口比較少,就不再繼續一一列舉了。另外一個定制功能在於SFSafariViewControllerDelegate里面的一個方法:
-(NSArray<UIActivity *> *)safariViewController:(SFSafariViewController *)controller activityItemsForURL:(NSURL *)URL title:(nullable NSString *)title;
這個代理會在用戶點擊動作(Action)按鈕(底部工具欄中間的按鈕)的時候調用,可以傳入UIActivity的數組,創建添加一些自定義的各類插件式的服務,比如分享到微信,微博什么的。
圖2 SFSafariViewController演示截圖
小細節:
- SFSafariViewController有保存Cookies的功能,但是貌似不能和Safari瀏覽器共享,也可能是Beta版的bug