大多数浏览器和
Developer App 均支持流媒体播放。
-
建立可扩展企业App套件
了解如何构建能够协同重点企业工作的 app 。在本视频中,我们将向你介绍一组涉及 Apple 零售的企业 app,该套件可帮助员工与客户互动、跟踪运营、管理商店以及保持联系。了解 Apple 零售如何通过采用 Swift 包、测试 app 可扩展性来创建一套统一的 app。探索用配置管理生产中的 app 如何帮助不同的地区和区域来量身定制 app 套件。
资源
相关视频
WWDC20
WWDC19
WWDC18
-
下载
大家好 欢迎来到全球开发者大会 (建立可扩展企业App套件) 大家好 我是艾瑞克 我和我的同事皮纳 我们一起管理零售商店App移动工程团队 今天我们想来讨论构建可靠、灵活 和便于维护的企业app Apple有超过500家商店 不断致力于重新定义零售体验 优秀的零售店员是我们零售运营的核心 我们开发可为他们提供支持的app 从商店预定管理系统 到 以及店内布局管理 所有这些构成了一个流畅的系统 确保我们的商店顺利运营 现在你大概了解了我们工作的目的 接下来的内容就是讲我们如何进行工作 以及你怎样可以将同样的操作 运用到你自己的企业app中去 我们的内容大纲包括 app间共享的架构设计 这其中涵盖了一些你在开发新app 或者在对现有app进行重新架构设计时 应该考虑到的一些基本原则 我们还会涉及到app开发后的测试 最后 皮纳会讨论app在进入生产环境后 一些管理的相关内容 在开发一款app时 iOS中有许多功能 可以使多个app很好地协同工作 我来列举其中几个 启用App Groups Swift软件包的好处 以及寻找优秀的软件包候选项 App Groups是我们在开发app套件时 最先利用的iOS功能之一 一旦启用了这个功能 我们就可以将多类型数据 通过UserDefaults和共享文件进行共享 所有这些设置 都可以在Xcode里你的项目文件中 通过签名和功能部分实现 来看看它是如何操作的吧 首先 点击添加功能按钮 然后选择App Group 这样可以添加一个新的App Group面板 选择面板上的加号键 将会添加新的App Group 它也会被添加到你的开发者门户中 这样同一个门户里其他的app也可访问它 一旦你在Xcode里设置好了你的App Group 共享数据就非常简单了 这个例子展示了如何通过 UserDefaults来共享数据 首先 我们在UserDefaults中 创建了一个实例 将它传到我们的App Group中初始化它 在初始设置过后 设置值就和调用赋值方法一样简单 通过字符串、整型数 Boolean等指定的数据类型方法 进行值的读取也同样简单 (Swift软件包的优点) 接下来 我们来谈谈Swift软件包 我们在查看现有的app时 以及在开发新的app时 使用Swift软件包有很多原因 最显著的原因就是它可以减少代码重复 这就缩短了我们的开发时间 同时也降低人工错误的风险 从而提高了我们app的可靠性 它也给我们的组织提供了更多的灵活性 可以以更低的入职学习成本 让人员在团队间进行流动 因为大家已经熟知大部分的代码库 我们还组建了 一支专门负责开发软件包的团队… (提高代码领域专注度) …让他们可以把精力 更多地集中在软件包解决的问题上 在完成iOS app的开发后 我们的团队 会识别出许多优秀候选项的部分 (Swift软件包 寻找优秀的软件包候选项) 跟你们很多人一样 Apple在我们的app中 普遍使用标准认证方法 正因如此 认证是个绝佳的选择 我们的认证是在建立URLSession的基础上 这样 工程师就不必考虑认证的事 可以让他们与服务器进行交互 好像认证不存在一般 另一个网络相关的软件包 用于图片缓存和获取 它可以让我们把图片列队 并且按需将它们缓存到磁盘中 同样 这也可以让我们的工程师 不必担心网络连接和图片来源的问题 (用户界面元素) 我们的所有东西 都是在UIKit的基础上开发的 我们使用自定义TableView Cell 和产品DetailView 将其打包 以确保一致性 同一个用户界面会用在多个app中 (app模型层) 我们的很多app都有相似的对象 比如用户、预订和产品 这些模型对象是提取到Swift软件包 并在所有app间共享的 主要候选项 能够实现我们模型的标准化定义 我今天想讲的最后一个软件包 是我们的扫描软件包 它是我们在计算机视觉 和AVFoundation的基础上建立的 为我们的条形码 QR码 和文字识别提供了一个 在所有app中常见的外观 让我来展示一下它的样子 通过计算机视觉框架 我们的软件包可以扫描多种符号 比如PDF417 DataMatrix码和QR码 此外 我们通过它还能进行实时的 光学字符识别以捕捉基于文本的数据 在计算机视觉框架之上 我们还建立了一个层 用于展示补充用户界面视图 帮助用户瞄准相机 自定义辅助功能支持 控制闪光灯 以及简化配置 从而获得一个简洁通用的API 让我们来看看它们是什么样的 不论扫描条形码还是文字 我们代码的模式都是一样的 设置很简单 初始化合适的视图控制器 传递含有配置选项的结构 然后分配委托 对工程师来说就是这么简单 委托可处理扫描过程中 成功和失败的信息传递 我来进一步展示它的工作原理
我们在这里创建一个scanOptions的实例 也就是一个包含扫描软件包配置的结构 然后初始化一个新的 BarcodeScannerViewController 也用同样的配置 这个配置/初始化模式 使我们可以在不同的app上轻松保存 并重新使用 接下来的例子和第一个很相似 和条形码扫描不同 这个控制器可扫描识别视图区域内的文本 我们保留了和条形码案例中 相同的配置/初始化模式 可以轻松快捷地使用任何一个软件包 有了这两个元素 我们的API 可以提供一个默认用户界面 这个用户界面可以被替换 或根据每个app的需要进行完全定制 这使得我们可以轻松保持 所有app中用户界面的一致性 我们谈到了App Groups和Swift软件包 现在我们来谈谈测试 在app开发出来后 我们当然需要测试一下 确保它们可以达到如期效果 我们当然可以找一大群人来做这件事 但是我们有更高效的方式来完成这项工作 让我们来看看最常见的几个案例吧 其中三个包括单元测试 用户界面测试以及性能测试 (测试方法) 单元测试是我们测试策略的第一步 由工程团队开始进行 (通过XCTest进行单元测试) 他们在编写带动app的类和函数时 创建单元测试很重要 这样能确保返回每个代码路径所预期的值 Xcode为使用XCTest框架的单元测试 提供了绝佳的支持 使你能够很快地编写和运行测试 要获取更深入的信息 有很多讲座可以观看 我会推荐从《在Xcode中测试》 和《测试方法与技巧》开始
(通过XCUITest进行用户界面测试) 我们会尽可能多地使用用户界面测试 因为这可以大大提高效率 用户界面测试会使用质量工程师团队 创建的手动测试用例 将它们在Swift中进行编码 Xcode自带的XCUITest 可以提供构建和运行他们的结构
一旦创建好这些测试 我们会按重要性进行划分 测试需要一定的时间 通过优先级进行划分 可以让我们更频繁地运行最重要的测试 测试越频繁 我们就能越快地找出错误 我们会按次测试 也会每天和每周进行固定测试 更多信息可以从全球开发者大会的 《Xcode 7中的用户界面测试》中获取
当我们在关注iOS设备的性能测试时 我们真正关注的只有两个点 渲染性能和电池性能 (性能测试 渲染性能) 现代iOS设备中的中央处理器 和图形处理器十分强大 但是我们仍需要注意我们app中的 每次交互的性能 没什么比界面滚动不流畅 或者拖动操作有延迟 更让用户沮丧的事情了 电池性能同样也十分重要 我们的设备会在商店中全天运行 如果雇员需要离开柜台 将他们的设备带到充电区 这会降低生产力 更不用提我们还要配备额外的设备 工程师们刚好有款优秀的工具 可以帮忙轻松直接地完成这些任务 就是Instruments Instruments是Xcode中自带的一种工具 可以帮助我们分析app中 包括执行时间长 内存占用大、电量消耗多在内的许多问题 想要了解更多关于Instruments的信息 请查看《实现App高性能的实用方法》 以及《提高电池寿命及性能》这两篇讲座 现在我将接下来的时间交给皮纳 来聊一聊app在生产环境中的管理问题 谢谢你 艾瑞克 听完艾瑞克为大家分享的这些丰富内容后 你可能会好奇 我们如何利用配置 管理在生产环境中的app 首先 我会讨论在研发时 为什么要考虑app配置 然后会讲到向后兼容 以及要求用户强制升级的一些内容 我们的app目前 同时支持两种配置 基于客户端的配置文件 和基于服务器上的配置文件 其本质就是从我们的服务器上 下载的Boolean值 我们首先来讲基于客户端的配置 (由配置文件带动的app流程 对于app体验的控制) 拥有一个嵌入在客户端 但同时承载在服务器上的配置文件 可以让我们在app的用户体验中 有更大的灵活性和适应性 这些元素可以在地区、市场 以及我们的 Apple零售商店层面上进行操作 在生产环境中 更改这些属性不需要修改代码 因此不需要构建新的客户端 这使得我们的app可以高度适应 不断变化的商业需求
我们的app同时也含有服务器的配置 它也可以带动app的行为 (数据流的控制) 我们依靠服务器中的数据来显示某些元素
这为一些 不使用某些功能的特定地区、市场 和Apple零售商店提供了很大的灵活性
我们的服务器可以根据市场全球化程度 开启或者关闭某些功能
和可靠的客户端配置一样 更改服务器上的值 也不需要修改代码 一旦把配置好的值部署到服务器上 它所带来的变化 会自动体现在app的行为上
业务和运营团队也可以接触到 服务器的配置 他们可以单独控制所设置好的值 他们可以根据业务需要 开启或者关闭某些功能
这些合作可以节省开发者 维护这些配置的时间 让他们可以完全投入到技术工程当中
这里有一个高层次的示例 向大家展示这些配置 是如何在你的app中运作的 通过客户端配置 你可以创建一个属性列表文件 包括所有你想要的属性 你的服务器可将这些文件存储为JSON格式 在启动程序时 你的app会下载所有设置好的属性 如果出于任何原因 在生产环境中 你想要更改某个属性的值 你可以直接在属性列表文件中修改 然后将新版配置文件上传至服务器 当你再次打开app时 这些修改就会被应用到上面 我会用几分钟的时间 通过一个例子为大家展示如何操作 通过基于服务器的配置 你的业务和运营团队 可以完全掌控值的设定 这样他们可以在全球层面上 开启或关闭功能 修改值以适应业务和市场需要 你的iOS app可以获取服务API 在那里设定这些属性 这些标志会最终带动你app的行为
我们来看一个基于客户端配置的例子 这里是我们要为客户表单定义的所有字段 有姓、名、电子邮箱和电话号码 也许还有我们希望从客户那里 收集的其他信息
这些属性会被谨慎地映射到客户端代码中 并且在我们的函数定义中 保持最大限度的通用状态 这样我们可以把它们用在属性列表文件中 这我们的app用户界面 在生产环境中的形式 现在 比如说相关方不再需要收集 客户的电子邮箱地址 希望马上将这一字段从用户界面中删除
我们可以简单地通过删除 配置属性列表文件中电子邮件这一字段 再将新版配置文件上传至服务器来完成 当再次打开app时 电子邮件这一字段就不见了 不用修改代码 不用构建新的客户端 就这么简单 (删除电话字段) 比如现在相关方也不需要收集 客户的电话号码 想要马上进行更改 我们可以重复相同的步骤 将新版配置文件上传至服务器
同样的 有了新的配置文件 电话号码字段也不再显示了 正如你所看到的 由配置所带动的用户体验 可以让我们在管理生产环境中的app时 拥有极大的灵活性和适应性 有了服务器和客户端的良好配合 我们也不能忘记向后兼容的问题 因为服务器上新的修改 旧的客户端不一定支持 反之亦然 从我们的经验来看 把配置版本的工作做好 为我们做出明确的计划提供了很大的帮助 我们的app会检查启动时下载的 服务器和客户端配置的版本 然后我们可以决定对用户展示 或者不展示哪些用户体验 当然 有时候 我们也需要用户强制升级他们的app 否则他们无法看到我们开发的新功能 (强制更新) 当客户端为属性添加了一个新的值 但服务器没有相应的映射 服务器和客户端就不能相互支持 这种情况下 要求用户强制升级就很有必要 总结一下 我们今天讲到了App Groups 共享框架和测试 讲到了运用由配置所带动的用户体验 最后讨论了向后兼容 和要求用户强制升级的必要性 谢谢观看 我们期待见到大家用iOS 14开发的app 希望大家今年在 全球开发者大会上参会愉快 祝你安康 再见
-
-
2:02 - App Groups
let sharedDefaults = UserDefaults(suiteName: “group.com.apple.myappgroup")! sharedDefaults.set("My Cool Value", forKey: "MyKeyName") let myKeyNameValue = sharedDefaults.string(forKey: "MyKeyName")
-
5:04 - BarcodeScannerViewController
import RetailScanner let scanOptions = BarcodeScanOptions() scanOptions.scanRegion = .regular scanOptions.shouldAddSupplementaryView = false scanOptions.shouldShowBarcodeDetector = true let barcodeViewController = BarcodeScannerViewController(scanOptions: scanOptions) barcodeViewController.delegate = self
-
5:29 - OCRScannerViewController
import RetailScanner let scanOptions = OCRScanOptions( scanRegion: .custom(CGSize(width: 400, height: 100)), accessibilityBehavior: .vibrate, shouldAddSupplementaryView: true, validation: nil, shouldShowResultView: true ) scanOptions.recognitionLevel = .fast let ocrViewController = OCRScannerViewController( scanOptions: scanOptions ) ocrViewController.delegate = self
-
12:26 - Config-driven UI - Client based configuration hosted by server
func configuredCellForLabel(for customerInfoField: CustomerInfoField, at indexPath: IndexPath) -> UITableViewCell { . . . } func configuredCellForPhoneNumber(for customerInfoField: CustomerInfoField, at indexPath: IndexPath) -> UITableViewCell { . . . }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。