◆ ◆ ◆
简介
在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
进去应该就会有审核规范进去。