此次分享主要分为两个部分: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项目中内嵌一个开发工具,好比:
一些资料