◆ ◆ ◆
简介
在 iOS14
中苹果推出了很多新个性,其中就蕴含 App Clips
。App Clips
相似微信的小程序,不须要显式的去 App Store
里下载,苹果会在对应的机会进行下载。App Clips
能够在不关上主 App 的状况下,独自进行应用,交互操作和主 App 无异,例如登录、列表视图、领取等。
为了保障加载速度,苹果对 App Clips
的安装包大小有限度,从产品设计的角度,就要聚焦外围性能,这也是苹果所举荐的。
因为公司打算做App Clips
,所以有了这篇文章,文章中的内容基本上能保障准确性,并且其中很多技术点是和苹果开发者沟通过的。
◆ ◆ ◆
应用流程
通过 Safari Banner
、iMessage
等如下形式,能够关上 App Clips
。例如点击Safari Banner
调起 App Clips
,调起时会带一个 URL 过去,零碎会依据调用 URL 来确定卡片显示的数据,随后将数据例如题目、背景图等显示在App Clips
的卡片页。
主题目下方有几行小字,能够抉择是否开启告诉、定位等权限,这些权限都是临时性或受限制的,能够点击蓝字进去将权限敞开,否则默认权限是关上的。点击 Open 即可进入 App Clips
中,并且将 URL 传给App Clips
。
◆ ◆ ◆
开发
App Clips
从 iOS14
开始反对,所以能够间接用 SwiftUI
进行开发,这也是苹果所举荐的开发模式。
◆ ◆ ◆
调起
App Clips
以主工程的一个 target
的模式存在于我的项目中,与主工程共享代码及资源文件。App Clips
能够拜访蓝牙、NFC 等硬件,相当于一个 smart app
。主 App 和App Clips
是互斥的,下载主 App 后 App Clips
就会被删除,所以如果有主 App 则调起客户端,没有客户端则调起App Clips
。
App Clips
是通过 URL 的形式调起的,能够间接应用配置的 URL,也能够在其前面拼接门路和参数,和咱们应用的申请 URL 相似。从内部调起的时候就会传入一个 URL 过去,App Clips
进行解析以调起对应的页面。
有一点须要理解的是,在 WWDC2020
中,苹果演示的是一个相似于微信小程序二维码那样的异形码。通过和苹果开发者沟通,并不强制要求用异形码,二维码就能够,次要是承载 URL 即可。
◆ ◆ ◆
二进制下载
对于 App Clips
二进制的下载有两种状况,一种是手机解锁的状况下,零碎会在卡片页展现过程中就开启后盾下载,点击 Open 按钮即可关上App Clips
。如果过后二进制还未当初完,则会呈现零碎的 loading 页面,loading 实现后即可关上App Clips
。
如果调起 App Clips
时手机处于锁屏状态,在卡片页不会开启后盾下载,当用户点击 Open 后才会开始下载并展现 loading 页面。
下载后的 App Clips
,三十天内未应用则会被删除二进制,下次应用将从新下载。这个卡片页无论是否装置 App 都会显示,区别在于关上的是主 App 还是App Clips
。Clip Card
只会显示一次,如果 App Clips
二进制没有被删除的话,之后就不会再反复显示。563513413,不论你是大牛还是小白都欢送入驻
◆ ◆ ◆
Apple Connect 配置
每个应用程序只能有一个 App Clips
,但能够有多个配置,能够定义题目、副标题、封面图(有大小限度)、按钮类型(action),题目默认和 App 名一样。每个App Clips
能够配置多个 URL,苹果举荐不同功能模块,对应不同的 URL。也能够只配置一个 URL,前面通过拼接门路和参数的形式来辨别和传值。原则上来说,URL 的数量没有限度。
配置 App Clips
时能够抉择高级设置,在高级设置中能够多套题目和封面图。苹果会依据配置的 URL 作辨别,显示不同的封面图。
◆ ◆ ◆
客户端配置
在主工程中新建一个 target
并抉择为 App Clips
,并且关联到咱们的主工程 Fruta 即可。因为App Clips
是从 iOS14
推出的,而 SwiftUI
是从 iOS13
推出的,所以咱们能够抉择应用 SwiftUI
进行开发,这也是苹果举荐的开发计划,当然也能够抉择 UIKit
的形式。
创立 App Clips
后,零碎会生成对应的 iOSClip.entitlements
文件,须要在外面设置 App Group
、Parent Identifier
、Associated Domains
,以关联主 App。咱们填写应用程序标示符时,苹果举荐以{App Bundle id}+Clip
的格局命名,这种命名也更清晰一些。
◆ ◆ ◆
客户端代码
客户端进行开发时,无论采纳 UIKit
还是 SwiftUI
,都是通过NSUserActivity
对App Clips
传入的 URL 做解析解决,并依据 URL 解决不同的业务逻辑,这块和 Unversal Link
的解决有点相似。对于 URL 的解决,应用 UIKit
和SwiftUI
的解决形式不同,如果是 UIKit
则采纳上面的办法解决 URL 传参。
UIKit
通过 UIScene
的代理办法接管回调,例如上面的形式。
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else {return}
guard let url = userActivity.webpageURL else {return}
presentExperience(for: url)
}
func presentExperience(for url: URL) {
// Route user to the appropriate place in your App Clip.
}复制代码
SwiftUI
的解决形式须要注册一个 NSUserActivityTypeBrowsingWeb
类型的 userActivity
,并在回调办法中解析webpageURL
即可。因为如果装置主 App 后,这个操作就要交由主 App 来解决,所以主 App 也须要有雷同的解决代码。
struct FrutaAppClip: App {
var body: some Scene {
WindowGroup {
NavigationView {SmoothieMenu()
}
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb, perform: handleUserActivity)
}
}
func handleUserActivity(_ userActivity: NSUserActivity) {
guard
let incomingURL = userActivity.webpageURL,
let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems
else {return}
}
}复制代码
◆ ◆ ◆
服务端开发
在关上 App Clips
之前,苹果会验证配置信息,验证形式是苹果申请公司服务器,公司服务器返回给苹果一个 JSON
格局的配置文件,App Clips
的 JSON
和Universal Link
的格局差不多。苹果要求设置的申请地址必须是 https
协定,并且不能进行重定向。这里的 appIDs
指的是 App Clips
配置的bundle id
。
上面是 App Clips
服务端配置 JSON
的示例,做过 Universal Link
开发的同学,对上面的 JSON
应该比拟相熟。
{
“applinks”: {
"details": [
{"appIDs": [ "ABCDE12345.com.example.app", "ABCDE12345.com.example.app2"],
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": "Matches any URL whose fragment equals no_universal_links and instructs the system not to open it as a universal link"
},
]
}
]
},
“webcredentials”: {
"apps": ["ABCDE12345.com.example.app"]
}
}复制代码
◆ ◆ ◆
数据共享
须要理解的是,App Clips
和主 App 是互斥的,当主 App 装置后,就会删除 App Clips
。二者的数据共享次要是沙盒的数据迁徙,所以在装置主 App 后就须要从App Clips
读取数据。
App Clips
和主 App 同步数据时,将二者的 group id
设置成雷同的即可,例如之前的 iWatch Extension
也有相似性能。这个 App Group
是须要在苹果后盾创立的,如果没有创立则须要进入开发者核心的 Groups
选项,创立的对应的group id
。
不同 target
或利用间拜访沙盒很简略,能够通过 NSUserDefaults
并传入对应的 group
的形式创立 userDefaults
对象,能够对 key
、value
进行操作。
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@”group.company.appGroupName”]; 复制代码
还能够通过 containerURLForSecurityApplicationGroupIdentifier
办法获取到沙盒门路,随后对文件进行操作。
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:APP_GROUP_ID];
NSURL *directoryPath = [containerURL URLByAppendingPathComponent:GroupShareRelativeDirectory]; 复制代码
◆ ◆ ◆
受权
App Clips
的设计初衷就是简略并聚焦外围性能,所以对于一些利用性能权限也和一般 App 有区别。例如在应用定位性能时,App Clips
不须要用户的残缺受权,能够申请“局部受权”,用户能够在卡片页抉择是否敞开,就是卡片页下方蓝色按钮。
告诉也是一样的,不须要向用户申请受权,能够申请“局部受权”,选项也是默认关上的,在卡片页能够敞开。App Clips
的告诉在告诉核心显示时,和一般告诉看起来是一样的,但“局部受权”有效期八小时,失常弹窗受权有效期一周,咱们也能够抉择申请用户受权一般告诉。
App Clips
中设置“局部受权”,在 App Clips
的info.plist
配置中,通过 NSAppClipRequestEphemeralUserNotification
字段设置开启告诉,如果设置此字段后默认为开启,但用户能够点击 options
敞开告诉。定位也是一样的,字段为NSAppClipRequestLocationConfirmation
。
◆ ◆ ◆
代码差别
在开发 App Clips
过程中,因为二者大多数应用的都是同一份代码,有些代码可能与主程序有差别,并不能运行到主程序或 App Clips
上。能够通过在 Active Compilation Conditions
设置对应的环境变量,来辨别不同的target
。
判断代码如下。
if !APPCLIP
// Code you don’t want to use in your app clip.
else
// Code your app clip may access.
endif 复制代码
◆ ◆ ◆
利用举荐
能够在 App Clips
的下方显示一个叠层,来举荐用户下载咱们的 App,通过 SKOverlay
来进行配置。
func displayOverlay() {
guard let scene = view.window?.windowScene else {return}
let config = SKOverlay.AppClipConfiguration(position: .bottom)
let overlay = SKOverlay(configuration: config)
overlay.present(in: scene)
}复制代码
◆ ◆ ◆
本地测试
进行本地测试时,能够将在 Apple Connect
中配置的要测试的 URL,配置在 App Clips
的环境变量中,并以 _XCAppClipURL
进行命名来测试,记得将其勾选。
这里的域名须要和 Associated Domains
统一。
◆ ◆ ◆
留神点
- 上面这些库在
App Clips
不反对,编译时并不会报错,但调用时会呈现调用有效等问题。CallKit
、CareKit
、CloudKit
、HealthKit
、HomeKit
、ResearchKit
、SensorKit
、Speech
。 - 为了爱护用户隐衷,在
App Clips
中上面的API
禁止应用。通讯录、Files、相册、iTunes。 App Clips
无奈进行后盾流动,目前看次要是后盾网络申请。
◆ ◆ ◆
审核
App Clips
是作为应用程序的一部分参加审核的,所以须要随客户端版本上线。尽管 App Clips
和主 App 在一个 project
中,但并不占用主 App 的包体积。
然而对于 App Clips
的审核规范,通过和苹果开发者团队的沟通,截止目前还未有审核规范收回,预计要等 iOS14
进去应该就会有审核规范进去。