翻译自:openURL Deprecated in iOS10

译者:Haley_Wong

苹果在iOS 2 推出了 openURL:方法 作为一种打开外部链接的方式。而与之相关的方法 canOpenURL: 在iOS 9隐私控制里也禁止查询设备中已安装的App。 苹果在iOS 10 中已经弃用了openURL:这个旧方法,用openURL:options:completionHandler:来代替。这篇快速指南就是教你在iOS 10 下如何打开一个外部链接的文章。

(Haley_Wong注:canOpenURL:是在iOS 3中添加的;打开外部链接一般都是用来调起别的App,比如调起打电话、邮件、Safari、QQ、微信、支付宝等)

iOS 10 中的更新

苹果在UIKit相关的 What’s New in iOS 文档中提到:

The new UIApplication method openURL:options:completionHandler:, which is executed asynchronously and calls the specified completion handler on the main queue (this method replaces openURL:).

翻译如下:

新的UIApplication 方法`openURL:options:completionHandler:` 会异步执行,并在主队列中调用这个指定的 `completion handler`回调。

这个弃用的方法有一个要打开的URL 参数,并且返回一个表示成功或者失败的布尔值:

// Objective-C
- (BOOL)openURL:(NSURL*)url // Swift
open func canOpenURL(_ url: URL) -> Bool

iOS 10中的新方法:

// Objective-C
- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options
completionHandler:(void (^ __nullable)(BOOL success))completion // Swift
open func open(_ url: URL, options: [String : Any] = [:],
completionHandler completion: (@escaping (Bool) -> Swift.Void)? = nil)

它有三个参数:

* 要打开的URL。

* 一个可选字典(可参考下面的实例)。传一个空字典时,该方法的效果与 openURL:一致。

* 一个带有 成功与否 参数的 completion handler(可认为是闭包或block)。如果你对这个状态不感兴趣可以传Null。

iOS 10 下打开一个URL

这意味着如果你有一个只需要支持iOS 10以上的App,也不关心options 参数和 完成的状态,又不想 Xcode 报警告,你可以这样写:

// Objective-C
UIApplication *application = [UIApplication sharedApplication];
[application openURL:URL options:@{} completionHandler:nil]; // Swift
UIApplication.shared.open(url, options: [:], completionHandler: nil)

实际上,只要你仍需要支持iOS 9或者更早的版本,那么你就很可能要用回 openURL:老方法。

我们来看一个 使用 completion handler 来检查 链接打开状态的例子。

显示 Objective-C代码:

- (void)openScheme:(NSString *)scheme {
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:scheme]; if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[application openURL:URL options:@{}
completionHandler:^(BOOL success) {
NSLog(@"Open %@: %d",scheme,success);
}];
} else {
BOOL success = [application openURL:URL];
NSLog(@"Open %@: %d",scheme,success);
}
} // Typical usage
[self openScheme:@"tweetbot://timeline"];

我传了一个空字典作为options参数,我在 completion handler 中就打印了一下 success 值,也没做啥有用的事。 下面是 Swift 版代码:

func open(scheme: String) {
if let url = URL(string: scheme) {
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:],
completionHandler: {
(success) in
print("Open \(scheme): \(success)")
})
} else {
let success = UIApplication.shared.openURL(url)
print("Open \(scheme): \(success)")
}
}
} // Typical usage
open(scheme: "tweetbot://timeline")

Options 参数

UIApplication 的头文件中列了一个可用在 options字典中的key:

* UIApplicationOpenURLOptionUniversalLinksOnly:可以设置布尔值,如果设置为true(YES),则只能打开应用里配置好的有效通用链接。如果应用程序没有配置,或者用于禁止打开这个链接,则 completion handler 回调里的success为false(NO)。

为了覆写程序的默认动作(默认这个key的值是NO),我们需要创建一个字典,将对应的key 设置为true(YES),然后将字典传给 options 参数:

// Objective-C
NSDictionary *options = @{UIApplicationOpenURLOptionUniversalLinksOnly : @YES};
[application openURL:URL options:options completionHandler:nil]; // Swift
let options = [UIApplicationOpenURLOptionUniversalLinksOnly : true]
UIApplication.shared.open(url, options: options, completionHandler: nil)

举个例子,我把这个值设置为 true 并尝试打开https://twitter.com/kharrison, 如果我没有安装 Twitter 应用,它将会执行失败,而不是在Safari中打开这个链接。

(译者注:在iOS 9 使用 openURL:方法打开这个链接时,会在首先调起Safari,然后在Safari中打开这个链接)

更多阅读

如有翻译错误,请批评指正,谢谢!

(译)openURL 在 iOS10中已弃用的更多相关文章

  1. vSphere6提示已弃用VMFS卷的解决方法

    Deprecated VMFS volume(s) found on the host. Please consider upgrading volume(s) to the latest versi ...

  2. [译] OpenStack Pike 版本中的 53 个新功能盘点

      原文:https://www.mirantis.com/blog/53-things-to-look-for-in-openstack-pike/ 作者:Mirantis Nick Chase 发 ...

  3. [译]聊聊C#中的泛型的使用(新手勿入) Seaching TreeVIew WPF 可编辑树Ztree的使用(包括对后台数据库的增删改查) 字段和属性的区别 C# 遍历Dictionary并修改其中的Value 学习笔记——异步 程序员常说的「哈希表」是个什么鬼?

    [译]聊聊C#中的泛型的使用(新手勿入)   写在前面 今天忙里偷闲在浏览外文的时候看到一篇讲C#中泛型的使用的文章,因此加上本人的理解以及四级没过的英语水平斗胆给大伙进行了翻译,当然在翻译的过程中发 ...

  4. react的类型检查PropTypes自React v15.5起已弃用,请使用prop-types

    最近使用React的类型检查PropTypes时,遇到错误:TypeError: Cannot read property 'array' of undefined 看了下自己的React版本:    ...

  5. android/java 根据当前时间判断股票交易状态(未开盘 交易中 休市中 已收盘)

    /** * @param data yyyy-MM-dd HH:mm:ss 时间 * @return 未开盘 交易中 休市中 已收盘 */ public static String getSotckS ...

  6. ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

    问题:ObjectStateManager 中已存在具有同一键的对象.ObjectStateManager 无法跟踪具有相同键的多个对象. 解决方案:在查询的时候加上AsNoTracking()就ok ...

  7. HttpTool.java(在java tool util工具类中已存在) 暂保留

    HttpTool.java 该类为java源生态的http 请求工具,不依赖第三方jar包 ,即插即用. package kingtool; import java.io.BufferedReader ...

  8. 无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支

    无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支.发布此分支将导致远程存储库中的分支发生非快进更新. 第一次用oschina的git设置完远程仓库后提交出现 ...

  9. 用户、组或角色 '' 在当前数据库中已存在。 (Microsoft SQL Server,错误: 15023)

    SQLServer2008用户组或角色'*****'在当前数据库中已存在问题的解决办法 在迁移数据库的过程中SQLServer SDE的问题 为一个数据库添加一个用户时,提示以下信息:用户.组或角色 ...

随机推荐

  1. bcrypt对密码加密的一些认识(学习笔记)

    学习nodejs和mongoDB的时候,接触了用户注册和登录的一些知识. 1.关于增强用户密码的安全性 用户的密码肯定不能保存为明文,避免撞库攻击. 撞库攻击:撞库是一种针对数据库的攻击方式,方法是通 ...

  2. 前端之旅HTML与CSS篇之IE6常见BUG

    1.IE6怪异解析之padding与border算入宽高原因:未加文档声明造成非盒模型解析解决方法:加入文档声明<!doctype html> 2.IE6在块元素.左右浮动.设定marin ...

  3. [LeetCode] Minimum Index Sum of Two Lists 两个表单的最小坐标和

    Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite ...

  4. [HNOI2016]最小公倍数

    题目描述 给定一张N个顶点M条边的无向图(顶点编号为1,2,...,n),每条边上带有权值.所有权值都可以分解成2a∗3b2^a*3^b2a∗3b 的形式. 现在有q个询问,每次询问给定四个参数u.v ...

  5. ●BZOJ 1416 [NOI2006]神奇的口袋

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1416题解: Pòlya瓦罐模型: 给定罐子里每种颜色的球的个数A[i],按题目要求随机操作若 ...

  6. C++primer学习——左值和右值

    定义: 左值:用的是对象的身份 右值:用的是对象的值(内存) decltype: 当其作用于表达式时,如果求值结果是左值,那么返回一个引用 如果求值结果是右值,那么返回正常 int*p; declty ...

  7. 洛谷4月月赛R1

    T1.题目大意:n个人站成一排,有m个团队,每个人有且属于一个团队,可以让若干个人出队,任意交换这些人的位置后再站回去,问要让所有同一团队的人连续地站在一起,至少要出队几个.(n<=10^5,m ...

  8. 简述RIP路由协议和OSPF路由协议的相同点和不同点。

    路由协议分为静态路由协议和动态路由协议.动态路由协议有很多种,如RIP.OSPF.EIGRP等. 1.RIP(路由信息协议)是路由器生产商之间使用的第一个开放标准.RIP有两个版本:RIPv1和RIP ...

  9. ubuntu 16.04 安装 tensorflow-gpu 包括 CUDA ,CUDNN,CONDA

    ubuntu 16.04 安装 tensorflow-gpu 包括 CUDA ,CUDNN,CONDA 显卡驱动装好了,如图: 英文原文链接: https://github.com/williamFa ...

  10. JSSDK实现微信自定义分享---java 后端获取签名信息

    一.首先说下关于微信Access_token的问题,微信Access_token分为2中: 1.授权token获取方式: 这种token需要code值(如何获取code值查看官方文档) "h ...