Apple Silicon Mac 上的 iPad 与 iPhone App 运行

Stella981
• 阅读 936

作者:我就是御姐我摊牌了,iOS / Flutter 开发者,目前就职于美团,负责探索 Flutter 在业务容器上的落地实践

Sessions: https://developer.apple.com/videos/play/wwdc2020/10114/

今年 WWDC 最为重磅的消息可能就是 Applie Silicon Mac——搭载着苹果自研芯片的 Mac。得益于 CPU 架构的统一,在 Mac上原生的运行 iPhone 或者 iPad App 似乎已经不是那么的遥不可及了。相信很多人都会好奇苹果将会用什么样的方式将这些移动设备上的 App 带到我们手中的 Mac 上。Session 10114 iPad and iPhone apps on Apple Silicon Macs[1] 就是对这些疑问的一个统一回答。

概述

简单来说,Session 10114 主要向我们传达了这几个信息:

  • 运行方面:在不依赖 macOS 系统没有的 SDK 的前提下,所有的 iPhone/iPad App 在 Apple Silicon Mac 上都可以无需改动运行起来,只是很多地方看起来会不那么符合 macOS 风格,结合 Catalyst 会让我们的 App 在 macOS 上更好用

  • 调试方面:调试运行在 Mac 上的 iPhone/iPad 的过程和在模拟器、真机上完全相同

  • 发布方面:默认所有的 iPhone/iPad App 都可以发布到 Mac App Store,开发者可以选择手动关闭,同时像 Ad Hoc 或者企业分发这种 App Store 外的发布流程也和之前基本相同

接下来,我们来详细了解一下苹果的工程师都说了什么。

运行

在有 Apple Silicon Mac 之前,在 macOS 上我们一般会开发这四种类型的应用程序:

  • Mac apps:基于 AppKit 开发,比较老牌的一种开发方式

  • Mac Catalyst apps:在 macOS Catalina 后才支持的开发方式,基于 UIKIt 开发

  • Web Apps:基于前端技术栈开发,比较老牌的一种开发方式

  • Games:基于 Metal 框架开发,相对比较新的一种开发方式

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

得益于 Catalyst 在 macOS 上引入的 UIKit,在 Apple Silicon Mac 上,我们可以非常轻松的运行原本运行在 iPhone/iPad 上的 App。

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

默认运行起来的这些 App 在很多方面上都可以获得类似 macOS App 的体验,包括:

  • Standard window chrome(就是 Mac app 左上角的那三个按钮)

  • Menu bar

  • macOS app lifecycle

  • Preferences panel

  • Dock presence

  • Dark Mode

  • Open/save panels(CMD + O / CMD + S会打开的那个面板)

  • Text behaviors

  • Font and color panels

  • Scroll bars

  • Touch Bar

  • Printing

  • Alerts

  • Drag and drop(和 iOS 上的类似,通过拖拽将一个 App 中的内容移动到另一个 App 中,参见 Human Interface Guidelines - Drag and Drop [2])

注意:

尽管以上这些内容是可以自动获得的,但仅仅有这些能力并不足以让一个 App 在 macOS 获得良好的体验,这些 App 仅仅是处于 “能用” 的状态。如果想要让 App 在 macOS 上“好用”,苹果的工程师建议我们使用 Catalyst 来优化 App 的体验。

不过获得以上这些体验的前提是,App 能够在 macOS 上正常的运行起来。

要想让 App 能够在 macOS 上正常的运行起来,开发者需要关注这几个方面的事情:

  • App 没有依赖 macOS 上不存在的 API 或者是 SDK(包括系统的和第三方库的)

  • App 没有依赖 macOS 缺失的功能

  • App 没有依赖 Mac 所不具有的硬件能力

除此之外,在代码的健壮性上,开发者需要关注 iPhone/iPad App 在 Mac 上运行会有如下方面的不同:

  • 硬件上的不同

  • UI 上的不同

  • 系统软件上的不同

硬件上的不同

硬件方面,苹果的工程师主要提及了三点不同:

  • 鼠标与触摸事件的不同

  • 环境传感器的不同

  • 摄像头的不同

鼠标与触摸事件的不同

在 iPhone/iPad 上用户输入都是以触摸为主,而 Mac 则是以鼠标键盘为主。macOS 会尽量将普通的点击等事件映射成对应的触摸事件。但如果 App 实现了一些自定义的触摸事件,那么开发者就需要自己测试一下自己的 App 在 Apple Silicon Mac 上是否表现正常。

环境传感器的不同

iPhone/iPad 上都有着大量的环境传感器,例如加速剂、陀螺仪、GPS、磁力计、景深摄像头等,而在 Mac 上基本没有这些传感器。因此开发者要在代码做好没有这些传感器的对应处理。需要注意的是,没有传感器并不代表没有相应能力,例如在 Mac 上开发者依旧可以使用 CoreLocation 来获取设备当前的位置(只是不那么精确)。

摄像头的不同

在 iPhone/iPad 上几乎所有的设备都拥有前置和后置摄像头,但是在 Mac 上这种假设并不一定成立。苹果的工程师建议开发者,用 AVCaptureDevice.DiscoverySession[3] 这个 API 来获取摄像头设备的使用权限。

UI 上的不同

在 macOS 中,很多系统控件的行为表现会和 iPhone/iPad 上不太一样,例如 Alert:

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

所以 App 的代码中不要有任何类似假定系统控件弹出位置的代码,因为这些代码运行在 Mac 上时,会得到完全不同的结果。

同时注意,如果开发者的 iPad App 没有支持 Multitasking[4],会和 iPhone App 一样在 Apple Silicon Mac 上表现为一个不可以改变大小的窗口。

如果 iPad App 支持了 Multitasking,那么开发者需要保证布局代码足够的高效,以便用户在缩放窗口大小时能够得到流畅的体验。

系统软件上的不同

系统软件上的不同主要体现在两个方面:

  • 文件系统

  • 设备信息

文件系统

和 iPhone/iPad App 不同,Mac App 可能被用户放置在任何一个地方,因此 App 的代码中不应该对 App Bundle 以及沙盒的位置做任何硬编码。

设备信息

在 Mac 上,窗口的分辨率可能会有各种各样的变化,设备名称也可能有各种各样的变化,因此 App 内部不应该对设备的分辨率以及设备名称做任何假设(设备名称这一条 App 对应的后端服务也要注意,不要依赖设备名称)

调试

调试这部分可以讲述的东西不多,因为整体内容就可以用四个字来总结:完 全 一 致。不管是 Debug 的工作流,还是 Profile 的工作流,甚至单元测试的工作流都是完全一样的。

唯一值得一提的是,根据苹果工程师的说法,在 Apple Silicon Mac 上,使用 Xcode 打开 iOS 工程,在 Target 的 Destination Device 中会多一个 My Mac(Designed for iPad) 这样一个设备:

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

选择这个设备,运行起来后就会看到这样的效果——没有模拟器,直接运行在 Mac 上的 iOS App:

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

发布

如果说调试可以用四个字来形容,那么发布就可以用六个字来形容:基 本 完 全 一 致。

将 iPhone/iPad App 发布到 Mac App Store 的步骤和发布到 iOS App Store 的步骤是基本一致的,开发者需要做的就是同意新的开发者协议,然后把能够发布到 Mac 上的 App 勾选发布到 Mac 即可,整个过程就像是发布到一个新的设备类型一样。

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

通过这种方式发布的 App 同样也可以使用 StoreKit 完成应用内购买、AppThing 以及 On-demand Resources 这些 iOS App Store 提供的功能,唯一有所区别的是,TestFlight 并不支持这种形式的 App。

同样的过程也体现在 Ad Hoc/Enterpirse/Development 发布的过程中,整个过程中开发者只要将 Mac 当做一个新的设备类型发布即可。

除此之外,在今年的晚些时候(熟悉的 Later in Summer),苹果还会提供一些新的开发者工具,帮助开发者更好的验证他们的 App 在 Apple Silicon Mac 上的表现。

总结

虽然形式非常不同,但是苹果 Catalyst + Apple Silicon Mac 的这套组合拳,让我不禁联想到了 IPad 早年推出的时可以运行 iPhone App 的操作。以成熟的生态带动一个不那么成熟的生态,进而创建/拉动一个新的生态。虽然现在只是一个开始,但说不定过几年再看我们会发现:

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

推荐阅读

将移植 Mac app 到 Apple Silicon

关注我们

我们是「老司机技术周报」,每周会发布一份关于 iOS 的周报,也会定期分享一些和 iOS 相关的技术。欢迎关注。

Apple Silicon Mac 上的 iPad 与 iPhone App 运行

关注有礼,关注【老司机技术周报】,回复「2020」,领取学习大礼包。

支持作者

这篇文章的内容来自于 《WWDC20 内参》。在这里给大家推荐一下这个专栏,专栏目前已经创作了 109 篇文章,只需要 29.9 元。点击【阅读原文】,就可以购买继续阅读 ~

WWDC 内参 系列是由老司机周报、知识小集合以及 SwiftGG 几个技术组织发起的。已经做了几年了,口碑一直不错。 主要是针对每年的 WWDC 的内容,做一次精选,并号召一群一线互联网的 iOS 开发者,结合自己的实际开发经验、苹果文档和视频内容做二次创作。

参考资料

[1]

Session 10114 iPad and iPhone apps on Apple Silicon Macs: https://developer.apple.com/videos/play/wwdc2020/10114/

[2]

Human Interface Guidelines - Drag and Drop: https://developer.apple.com/design/human-interface-guidelines/macos/user-interaction/drag-and-drop/

[3]

AVCaptureDevice.DiscoverySession: https://developer.apple.com/documentation/avfoundation/avcapturedevice/discoverysession

[4]

Multitasking: https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/multitasking/

本文分享自微信公众号 - 老司机技术周报(LSJCoding)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
4个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这