为了纪念上周发布的iOS13,我们来看一看你现在可以在你的应用程序中使用的一些模糊的(基本上是没有文档的)API。我们已经清除了最好的部分IOS13发行说明API差异现在把它们呈现给你。
下面是我们最喜欢的一些从iOS 13开始可以做的事情:

生成URL的富表示

新的IOS 13,链接呈现框架提供一种方便的内置方式来复制您在消息中看到的URL的丰富预览。如果您的应用程序有任何聊天或消息功能,您肯定会想要检查这一点。

丰富的URL预览至少可以追溯到20世纪初,随着微格式由语义web先驱和早期先驱使用khtml2png若要生成网页的缩略图图像,请执行以下操作。快到2010年,随着社交媒体和用户生成的内容的兴起,facebook创建了OpenGraphProtocol允许网络出版商自定义其页面的外观时,张贴在新闻提要。

如今,大多数网站都有开放图形标签在他们的网站上,为社会网络,搜索引擎,以及任何其他链接被贩运的地方提供他们的内容摘要。例如,如果您对这个网页进行了“查看源”,您将看到以下内容:

<meta property="og:site_name" content="NSHipster" />
<meta property="og:image" content="https://nshipster.com/logo.png" />
<meta property="og:type" content="article" />
<meta property="og:title" content="iOS 13" />
<meta property="og:url" content="https://nshipster.com/ios-13/" />
<meta property="og:description" content="To mark last week's release of iOS 13, we're taking a look at some obscure (largely undocumented) APIs that you can now use in your apps." />

如果您想在应用程序中使用这些信息,现在可以使用LinkPresting框架的LPMetadataProvider类来获取元数据,并可选择地构造一个表示:

import LinkPresentationlet metadataProvider = LPMetadataProvider()
let url = URL(string: "https://nshipster.com/ios-13/")!let metadataProvider = LPMetadataProvider()
metadataProvider.startFetchingMetadata(for: url) { [weak self] metadata, error inguard let metadata = metadata else { return }let linkView = LPLinkView(metadata: metadata)self?.view.addSubview(linkView)
}

在设置适当的约束(或者调用sizeToFit()),您将得到以下内容,用户可以点击它预览链接的网页:

在startFetchingMetadata(for:)完成处理程序,您可以检查和变异从服务器检索的元数据。您可能会利用这个机会为没有这些内容的页面添加默认的图像/视频,将文本翻译成用户首选的语言之一,或者检查显式文本和媒体。

或者,如果您已经在-app中拥有元数据,或者不能或不希望远程获取元数据,则可以构造一个LPLinkMetadata直接:

let metadata = LPLinkMetadata()
metadata.url = url
metadata.title = "iOS 13"
metadata.iconProvider = ...let linkView = LPLinkView(metadata: metadata)

LPMetadataProvider在IOS上做广告,但MacOS客户端必须具有com.apple.security.network.client权限,以便从远程URL获取元数据。

执行设备上语音识别

SFSpeechRecognizer在iOS 13中获得一次重大升级-最显著的是它增加了对设备上语音识别的支持。

以前,抄写需要一个互联网连接,并且被限制在最多1分钟的时间内,每天的请求都有限制。但是现在,你可以完全在设备上和离线下进行语音识别,没有任何限制.唯一要注意的是,离线转录不如服务器连接的效果好,而且只适用于某些语言。

若要确定脱机转录是否可用于用户的区域设置,请检查SFSpeechRecognizer财产supportsOnDeviceRecognition…在出版时,所支持的语文清单如下:

根据IOS 13发布说明:“supportsOnDeviceRecognition属性总是返回false第一次被访问的时候。几秒钟后,再次访问它将返回正确的值。“

但这并不是iOS 13中的全部语音识别!SFSpeechRecognizer现在提供信息,包括说话速率和平均停顿时间,以及语音分析功能,如抖动(音高的变化)和闪光器(振幅的变化)。

import Speechguard SFSpeechRecognizer.authorizationStatus() == .authorizedlet recognizer = SFSpeechRecognizer()
else {fatalError()
}let url: URL = ...
let request = SFSpeechURLRecognitionRequest(url: url)recognizer.recognitionTask(with: request) { (result, error) inguard let result = result else { return }for segment in result.bestTranscription.segments {guard let voiceAnalytics = segment.voiceAnalytics else { continue }let pitch = voiceAnalytics.pitch.acousticFeatureValuePerFramelet voicing = voiceAnalytics.voicing.acousticFeatureValuePerFramelet jitter = voiceAnalytics.jitter.acousticFeatureValuePerFramelet shimmer = voiceAnalytics.shimmer.acousticFeatureValuePerFrame}
}

您的应用程序可以使用有关音调、语音和其他功能的信息(可能)。协同CoreML)区分说话人或从说话人的拐弯处确定潜台词。

发送和接收Web套接字消息

说到FoundationURL加载系统,我们现在已经有了本机支持的东西,这些东西在我们的愿望列表中占据了很多年的首位:Web套接字.

多亏了新的URLSessionWebSocketTask在IOS 13中,您现在可以像发送HTTP请求一样轻松可靠地在应用程序中集成实时通信-所有这些都没有任何第三方库或框架:

let url = URL(string: "wss://...")!
let webSocketTask = URLSession.shared.webSocketTask(with: url)
webSocketTask.resume()// Configure how messages are received
webSocketTask.receive { result inguard let .success(message) = result else { return }...
}// Send a message
let message: URLSessionWebSocketTask.Message = .string("Hello, world!")
webSocketTask.send(message) { error in...
}// Eventually...
webSocketTask.cancel(with: .goingAway, reason: nil)

对于web套接字的低级控制,包括客户端和服务器支持,请查看网络框架.

多年来,网络可能一直是整个苹果技术体系中移动最快的部分。每个WWDC,都有太多要谈论的话题,以至于他们不得不在两个不同的会议上打破他们的内容。2019年也不例外,我们强烈建议你花点时间看看今年的“网络进步”会议(第一部分, 第二部分).

用地图做更多

MapKit是Apple SDK的另一个组成部分,它在WWDC上年复一年地表现强劲。在我们日常生活中,影响最大的往往是那些小小的触碰。

例如,新的MKMapView.CameraBoundaryiOS 13中的API使得在不完全锁定地图的情况下将地图的视口限制到特定区域变得容易得多。

let region = MKCoordinateRegion(center: mapView.center,latitudinalMeters: 1000,longitudinalMeters: 1000)
mapView.cameraBoundary = MKMapView.CameraBoundary(coordinateRegion: region)

新的MKPointOfInterestFilterapi,您现在可以自定义地图视图的外观,只显示特定类型的兴趣点。(而以前是全无命题).

let filter = MKPointOfInterestFilter(including: [.cafe])
mapView.pointOfInterestFilter = filter // only show cafés

最后,用MKGeoJSONDecoder,我们现在有一个内置的方式来拉进来。GeoJSON来自Web服务和其他数据源的形状。

let decoder = MKGeoJSONDecoder()if let url = URL(string: "..."),let data = try? Data(contentsOfURL: url),let geoJSONObjects = try? decoder.decode(data) {for case let overlay as MKOverlay in geoJSONObjects {mapView.addOverlay(overlay)}
}

用JavaScript信守诺言

如果你喜欢我们的文章JavaScriptCore,你会很高兴知道JSValue对象现在本地支持承诺.

对于不熟悉的人:在JavaScript中,Promise表示异步操作的最终完成(或拒绝)及其结果值的对象。承诺是现代JS开发的支柱-也许最值得注意的是fetchAPI

iOS 13中JavaScriptCore的另一个补充是对符号(不,不是那些符号)。有关init(newSymbolFromDescription:in:), 参考文档 猜猜怎么用。

对目标C相关对象的响应(?)

在云雀上,我们决定看看目标C今年是否有什么新发现,并惊讶地发现objc_setHook_setAssociatedObject…同样,除了声明之外,我们没有什么可继续进行的,但是现在您似乎可以配置一个块,以便在关联对象已经设定好了。对于任何仍深入目标C运行时的人来说,这听起来很方便。

驯服活动项目(?)

关于失踪文件的问题:UIActivityItemsConfiguration似乎就像在新的iOS13共享表中管理操作的一个很有吸引力的选项,但是我们不知道从哪里开始…

遗憾的是,我们还没有足够的信息来利用这一点。

格式列表和相关时间

中讨论过的前一篇文章,IOS 13为基金会带来了两个新的格式:ListFormatter和RelativeDateTimeFormatter.

不是为了唠叨这件事,但他们都是仍然因此,如果您想了解更多信息,我们建议您从7月份开始查看这篇文章。或者,如果您很着急,下面是一个演示如何将两者结合使用的快速示例:

import Foundationlet relativeDateTimeFormatter = RelativeDateTimeFormatter()
relativeDateTimeFormatter.dateTimeStyle = .namedlet listFormatter = ListFormatter()
listFormatter.string(from: [relativeDateTimeFormatter.localizedString(from: DateComponents(day: -1)),relativeDateTimeFormatter.localizedString(from: DateComponents(day: 0)),relativeDateTimeFormatter.localizedString(from: DateComponents(day: 1))
]) // "yesterday, today, and tomorrow"

跟踪排队操作的进展

从iOS 13开始,OperationQueue现在有一个progress财产。

当然,(NS)Progress对象并不是最简单、最方便的东西(我们一直打算在某个时候写一篇关于它们的文章),但是它们有一个完整的、经过深思熟虑的API,甚至在应用程序框架中也有一些方便的插槽。

例如,检查连接一个UIProgressView若要以其方式显示操作队列的实时更新进度,请执行以下操作:observedProgress财产:

import UIKitfileprivate class DownloadOperation: Operation { ... }class ViewController: UIViewController {private let operationQueue = {let queue = OperationQueue()queue.maxConcurrentOperationCount = 1}()@IBOutlet private var progressView: UIProgressView!@IBAction private func startDownloading(_ sender: Any) {operationQueue.cancelAllOperations()progressView.observedProgress = operationQueue.progressfor url in [...] {let operation = DownloadOperation(url: url)operationQueue.addOperation(operation)}}
}

还值得一提的是13岁时出现的其他一些API,如schedule(after:interval:tolerance:options:?,哪条线索OperationQueue进入新的组合框架以一种很好的方式,而且addBarrierBlock(?,它的工作原理可能是调度屏障(虽然没有文档,但这是任何人的猜测)。

轻松管理后台任务

定义应用程序与竞争对手的区别之一是,它们使用后台任务来确保应用程序在下一次进入前台时得到充分同步和更新。

iOS 7是第一个提供用于调度后台任务的官方API (尽管在此之前,开发人员使用了各种创造性的方法)…但在这段时间里,多个因素-从iOS应用程序能力和复杂性的提高,到对应用程序的性能、效率和隐私的日益重视-催生了对更全面解决方案的需求。

该解决方案是通过新的iOS 13实现的。背景测试框架.

如今年WWDC会议所述“应用程序后台执行的进展”该框架区分了两大类背景任务:

  • 应用程序刷新任务:短命的任务,使应用程序一整天都保持最新。
  • 背景处理任务*用于执行可推迟的维护任务的长期任务

WWDC会话和附带的示例代码项目很好地解释了如何将这两者结合到您的应用程序中。但是,如果您想要它的快速要点,下面是一个应用程序从Web服务器定期刷新的一个小例子:

import UIKit
import BackgroundTasksfileprivate let backgroundTaskIdentifier = "com.nshipster.example.task.refresh"@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?lazy var backgroundURLSession = {let configuration = URLSessionConfiguration.background(withIdentifier: "com.nshipster.url-session.background")configuration.discretionary = trueconfiguration.timeoutIntervalForRequest = 30return URLSession(configuration: configuration, delegate: ..., delegateQueue: ...)}func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {...BGTaskScheduler.shared.register(forTaskWithIdentifier: backgroundTaskIdentifier, using: nil) { task inself.handleAppRefresh(task: task as! BGAppRefreshTask)}return true}func applicationDidEnterBackground(_ application: UIApplication) {scheduleAppRefresh()}func scheduleAppRefresh() {let request = BGAppRefreshTaskRequest(identifier: backgroundTaskIdentifier)request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 10)do {try BGTaskScheduler.shared.submit(request)} catch {print("Couldn't schedule app refresh: \(error)")}}func handleAppRefresh(task: BGAppRefreshTask) {scheduleAppRefresh()let url: URL = ...var dataTask = backgroundURLSession.dataTask(with: url) { (data, response, error) in...let success = (200..<300).contains(response?.statusCode)task.setTaskCompleted(success: success)}task.expirationHandler = {dataTask.cancel()}dataTask.resume()}...
}

以前进行背景更新的方法-即,UIApplication.setMinimumBackgroundFetchInterval(:)和UIApplicationDelegate.application(:performFetchWithCompletionHandler:)-现在已在IOS 13中被否决。

注释文本内容类型以获得更好的可访问性。
你知道听到一些人读出网址是多么令人沮丧吗?“eɪʧtipiˈkoʊlənslʃˈdʌbəljuˈdʌbəljudɑt”…)这就是当画外音试图在不了解更多信息的情况下阅读一些东西什么在看书。

iOS 13承诺通过新的accessibilityTextualContext财产和UIAccessibilityTextAttributeContextNSAttributedString属性键只要有可能,一定要用最能描述所显示的文本类型的常量对视图和属性字符串进行注释:

  • UIAccessibilityTextualContextConsole
  • UIAccessibilityTextualContextFileSystem
  • UIAccessibilityTextualContextMessaging
  • UIAccessibilityTextualContextNarrative
  • UIAccessibilityTextualContextSourceCode
  • UIAccessibilityTextualContextSpreadsheet
  • UIAccessibilityTextualContextWordProcessing

隐式删除从情节提要初始化的视图控制器中的未包装选项

SwiftUI可能已经预示了故事板的最终结束,但这并不意味着事情不是也不会继续好转,直到那一天到来。

对于斯威夫特纯粹主义者来说,在使用故事板进行iOS项目时,最令人恼火的反模式之一就是视图控制器初始化。由于Interface Builder的“准备”方法与SWIFT的对象初始化规则之间的阻抗不匹配,我们经常不得不在使所有属性成为非私有、变量和(隐式展开)选项之间进行选择,或者完全选择前面的故事板。

Xcode 11和IOS 13允许这些范例通过新的方式来协调它们之间的差异。@IBSegueAction属性和一些新的UIStoryboard班级方法:

首先,@IBSegueAction属性可以应用视图控制器方法声明来指定自己为API,负责创建segue的目标视图控制器。(即destinationViewController的属性segue参数中的prepare(for:sender:)方法).

@IBSegueAction
func makeProfileViewController(coder: NSCoder, sender: Any?, segueIdentifier: String?) -> ProfileViewController? {ProfileViewController(coder: coder,name: self.selectedName,avatarImageURL: self.selectedAvatarImageURL)
}

第二,UIStoryboard类方法instantiateInitialViewController(creator:)和instantiateViewController(identifier:creator:)提供一个方便的基于块的定制点来实例化Storyboard的视图控制器.

import UIKitstruct Person { ... }class ProfileViewController: UIViewController {let name: Stringlet avatarImageURL: URL?init?(coder: NSCoder, name: String, avatarImageURL: URL?) {self.name = nameself.avatarImageURL = avatarImageURLsuper.init(coder: coder)}required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}
}let storyboard = UIStoryboard(name: "ProfileViewController", bundle: nil)
storyboard.instantiateInitialViewController(creator: { decoder inProfileViewController(coder: decoder,name: "Johnny Appleseed",avatarImageURL: nil)
})

和新的UIKit场景在我们等待SwiftUI成熟和稳定的时候,iOS 13提供了大量的工作。

这是为了我们的iOS 13功能的总结性,你可能已经错过了。但是请放心-我们计划在未来的NSHipster文章中涵盖更多的新API。

如果遗漏了什么你想让我们来掩护,请通过加我们的交流群 点击此处进交流群 ,来一起交流或者发布您的问题,意见或反馈。

原文地址 https://nshipster.com/ios-13/#track-the-progress-of-enqueued-operations

iOS高级分享 — 谈谈 IOS 13相关推荐

  1. 微信团队原创分享:iOS版微信的内存监控系统技术实践

    为什么80%的码农都做不了架构师?>>>    本文来自微信开发团队yangyang的技术分享. 一.前言 FOOM(Foreground Out Of Memory),是指App在 ...

  2. 《iOS 高级编程》之Tableview进阶指南

    学习如何进阶使用UITableView,带给应用更高级的观感(look and feel) ●    学习如何开发自己定制的UITableView类,模仿iMessage应用的观感 ●    为一个基 ...

  3. 分享了iOS获取通讯录的4种方式

    本文实例为大家分享了iOS获取通讯录的4种方式,供大家参考,具体内容如下 使用场景 一些App通过手机号码来推荐好友,如 微博.支付宝 首先客户端会获取通讯录中的所有手机号然后将这些手机号提交到App ...

  4. 出一套 iOS 高级面试题

    一千个读者眼中有一千个哈姆雷特,一千名 iOS 程序员心目中就有一千套 iOS 高级面试题.本文就是笔者认为可以用来面试高级 iOS 程序员的面试题. 这套题的题目跟公司和业务都没有关系,而且也并不代 ...

  5. Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收(九)

    Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289 ...

  6. ios android分享代码,快速插入代码块——iOS Android

    昨天看到一篇分享插入代码块的文章 Xcode 快速开发 代码块,想到把我知道的其它方案也分享一下 iOS篇 这种方案可行,但效率不够高 方案二:Dash Dash 目前只有 macOS 版本,免费,但 ...

  7. 微信团队分享:iOS版微信的高性能通用key-value组件技术实践

    本文来自微信开发团队guoling的技术分享. 1.前言 本文要分享的是iOS版微信内部正在推广和使用的一个高性能通用key-value 组件的技术实践过程,该组件在微信内部被命名为MMKV(以下简称 ...

  8. ios 微信分享重新编码链接_微信民众号IOS端复制链接失足,安卓端分享链接翻开只能进入首页等题目的处理...

    近来在做某个需要在微信中翻开的项目,部份页面会经由过程微信分享或复制链接分享给其别人,然后就遇到了以下坑: 1.IOS端复制链接或在其他浏览器中翻开时,如果原网站链接原本应当是"http:/ ...

  9. H5 集成微信自定义分享(兼容 ios android)

    最近做 H5 集成微信分享踩了很多坑,多少辛酸泪只有经历了才能体会,仅以此篇文章记录其中的酸甜苦辣. 分享出去的效果大概是这样子的: 接到这个需求之后,因为之前也没有做微信相关开发的经验,于是查阅了一 ...

最新文章

  1. java中getter_Java中的Getter和Setters解释了
  2. lstm预测sin函数方法2思路的
  3. jQuery中增加新元素后没法响应原有的事件
  4. iOS进阶_Socket(Socket简介代码演练)
  5. 大剑无锋之post那么多优点,为什么还用get
  6. 基本的MySQL操作
  7. javaEE jdbc编程步骤
  8. Python Numpy 数组的初始化和基本操作
  9. 花园体育馆计算机房音乐教室的英语,新版PEP小学英语四年级下册期中复习资料1-3单元...
  10. soupUI生成webservice客户端代码
  11. 信息安全技术及应用 常规加密技术
  12. Latex安装与使用
  13. 非华为电脑安装华为电脑管家
  14. Linux系统各发行版镜像下载(借阅)
  15. 【数据维护】Windows文件保护机制(SFC)
  16. 如何免费的把 PDF 转换为 Word文档?
  17. 关于 傅里叶变换 的一些理解(通俗版)
  18. Postman发送请求失败报错“Error: getaddrinfo ENOTFOUND xxx.xxx.xxx.xxx“
  19. 推挽电路 MOS管、推挽输出和开漏输出
  20. python电话模块_Python常用模块

热门文章

  1. 为何你的生活那么无趣?
  2. 未明学院学员报告:做了微博数据分析后,我发现现在最火的明星原来是……
  3. linux不重启在线更换故障硬盘(大数据服务器单盘raid0条件下)
  4. vmware7.1汉化中文版序列号+注册机下载
  5. Folx Pro 5 Mac的专业下载工具,一款BT下载器
  6. Linux安装rar
  7. Angular数据绑定机制
  8. oracle 19 rac启动,19c RAC启动报LRM-00109
  9. 查询快递 批量查询物流信息并筛选无物流信息的单号
  10. uni-app微信小程序合成海报并保存到相册