此次分享主要分爲兩個部分:javascript
因爲分享過程當中間會穿插使用Xcode進行演示和口頭講解,文章只作了部分關鍵信息的羅列html
主要分爲4個層次:Cocoa Touch
、Media
、Core Service
和Core OS
。java
Cocoa Touch 觸摸UI層 顧名思義,其包含的不少框架是與用戶交互相關的,是開發 iOS App 的關鍵框架。提供了 App 的基礎結構,同時也提供了諸如:觸摸、推送、多任務處理、推送等系統服務。ios
其中 UIKit
是最經常使用的,用於界面的構建。git
Media 媒體層 提供對 App 處理各類媒體文件的處理能力,諸如:音視頻的編解碼,圖形繪製,製做動畫效果等。github
Core Services 核心服務層 包含全部 App 使用的基本系統服務。即便不直接使用這些服務,系統的許多部分仍是創建在它們之上。web
其中 Foundation
是最經常使用的,爲上層框架和App開發提供基礎功能,提供基本的數據類型和操做工具,諸如:集合類型處理、字符串處理、日期處理、文件處理、異常處理等。json
Core OS 核心操做系統層 包含大多數其餘技術所基於的底層功能。負責內存管理、文件系統任務、網絡處理和一些其餘的操做系統任務,還能直接和硬件設備進行交互。一般來講,大部分開發狀況不會直接使用與這一層打交道,上層框架會使用到它們。設計模式
鑑於通常Web開發者會接觸到iOS工程的狀況是使用React-Native
/Flutter
/Weex
初始化時自動建立的項目,因此先來看看工程文件都有些什麼:
.h
中聲明的方法,添加私有方法、屬性。宏定義
和 公共頭文件
XML
描述的View佈局文件xib
的強化版,一樣是使用XML
描述的佈局文件,但可放置、鏈接控制多個頁面跳轉邏輯Property List
(屬性列表),可用於存儲序列化後
的對象,經常使用用於存儲用戶配置
,輕量級的持久化方案文本
、圖片
、xib
、storyboard
圖片資源
,後續增長了顏色
等Cocoapods
)的配置文件,可類比成web項目的package.json
package-lock.json
Cocoapods
執行 pod install
安裝了依賴以後生成的(也可本身搞,是多個 xcodeproj
的合集)。光禿禿的直接解釋也不能很好的理解,因此藉着設計模式的示例工程來了解一下。
不過仍是有一些須要先講一講便於理解
因爲在 OC 中沒有命名空間的概念,因此經過加前綴的方式來避免衝突,通常開發者用本身名字/公司縮寫的大寫字母做爲前綴,Apple保留全部2個字母做爲前綴的權利。 其中 NS 表明的是NeXTSTEP,是喬布斯創立的 NeXT.Inc 公司開發的系統,其原生支持Objective-C,NeXT 1997年被 Apple 被收購,成爲Mac OS的基礎。 其餘諸如:UI -> UIKit、 AV -> AVFoundation/AVKit(Audio+Video)、CF -> CoreFoundation
一是關鍵字前帶@,如:@class
、@interface
、@implementation
、@end
、@protocol
等等 二是做爲語法糖,如字符串 @""
、基礎類型轉對象類型的數字@(1) @(YES) @(0.0)
、數組 @[]
、字典 @{}
等
詳見示例工程,此段主要爲分享中講解,文章中沒有體現
接下來咱們來講說 iOS 和 web 端開發協調相關的東西。
在 iOS 中有兩種webview,UIWebView
和 WKWebView
:
UIWebView (iOS 2.0 ~ 12.0) 在App進程中跑,加載頁面的內存是算在App佔用內存中的,當app內存超過限制時,會通知app處理,若未處理整個app會被kill。 已成歷史,2020年4月開始禁止新的App使用,年末禁止全部含有的App更新。
WKWebView (iOS 8.0 ~ ) 獨立進程,當其內存佔用超過系統分配給WKWebView的內存時,WKWebView會崩潰白屏並通知app進行處理,未處理app不會被kill。內存是 UIWebView 的1/3 - 1/4,啓動更快。異步處理與native橋接通訊的js。
碰上的主要是這幾個,更多其餘的能夠參考bugly的WKWebView 那些坑
相似於 mhc://b.maihaoche.com?type=xxx&value=xxx
<html> <header> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> // 給Native調用執行的方法 定義好 function showAlert(message){ alert(message); } // 經過發起iframe的方式打開一個 url-scheme function loadURL(url) { var iFrame; iFrame = document.createElement("iframe"); iFrame.setAttribute("src", url); iFrame.setAttribute("style", "display:none;"); iFrame.setAttribute("height", "0px"); iFrame.setAttribute("width", "0px"); iFrame.setAttribute("frameborder", "0"); document.body.appendChild(iFrame); // 發起請求後這個 iFrame 就沒用了,因此把它從 dom 上移除掉 iFrame.parentNode.removeChild(iFrame); iFrame = null; } // 點擊html按鈕 function firstClick() { loadURL("mhc://b.maihaoche.com?type=xxx&value=xxx"); } </script> </header> <body> <h2> scheme </h2> <button type="button" onclick="firstClick()">Click Me!</button> </body> </html> 複製代碼
須要服務器進行配置,可參考 iOS9 Universal Links踩坑之旅,移動應用之deeplink喚醒app
僅UIWebView可用
<html> <header> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> function secondClick() { // 調用native定義的方法 nativeShare('分享的標題','分享的內容','圖片地址'); } </script> </header> <body> <h2> JSCore </h2> <button type="button" onclick="secondClick()">Click Me!</button> </body> </html> 複製代碼
- (void)webViewDidFinishLoad:(UIWebView *)webView { JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; // 暴露給 web 調用的原生方法 nativeShare context[@"nativeShare"] = ^() { NSArray *args = [JSContext currentArguments]; for (JSValue *val in args) { NSLog(val.toString); } }; } 複製代碼
function btnClick() { // window.webkit.messageHandlers.方法名.postMessage(傳參數); window.webkit.messageHandlers.nativeShare.postMessage('params'); } 複製代碼
// 監聽web方法 - (void)setupScriptHandler{ [self.wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"nativeShare"]; } // 執行 web 調用 native - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([message.name isEqualToString:@"nativeShare"]) { // web傳遞過來的參數 NSLog(message.body); // objc 執行 web 方法 [self.wkWebView evaluateJavaScript:@"alert(\"分享成功\")" completionHandler:^(id _Nullable result, NSError * _Nullable error) { // web callback }]; } } 複製代碼
抹平UIWebView、WKWebView差別 WebViewJavascriptBridge
單純在pc端使用手機視圖模式,有時並不能保證其在 移動端瀏覽器/App 有一致的表現,那麼要怎麼調試呢?
須要對Mac/iOS端Safari進行簡單的設置
調試分兩種狀況,web頁是跑在 Safari 中仍是 App 中的,但不管如何都須要先把手機和電腦鏈接起來(無線鏈接跟局域網複雜程度有關,有的時候連不上,在家裏還行,在公司就別了)。
好比,在手機端Safari打開 www.baidu.com,會看到Mac端的Safari-開發-手機-多了以下圖的選項
打開後能夠看到下圖彈出一個常見的web檢查器工具,大部分操做點我相信大家比我熟悉,在這裏就提幾個小技巧吧:
= $* (* = 0、一、2.....)
,能夠直接的控制檯使用它首先,須要確認你手機的App是經過開發的同窗 使用Xcode直接Debug Run出來的(掃碼分發下載的不支持),或者模擬器使用拖進去的包也可(但記得給檢查一下模擬器的Safari的網頁檢查器是否打開)
web開發者也能夠直接在web項目中內嵌一個開發工具,好比:
一些資料