使用 URL 方案 iOS 中的应用程序间通信
Inter-app communication in iOS using URL scheme
我有两个测试应用程序:App1 和 App2。
App1 从文本字段中获取字符串并触发方法:
@IBAction func openApp(sender: AnyObject) {
let url1 = ("app2://com.application.started?displayText="+textToSend.text!)
let url2 = url1.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
UIApplication.sharedApplication().openURL(NSURL(string: url2!)!)
}
实际上打开了 App2,它只有标签,应该更改为通过 url 发送的文本,代码在 AppDelegate.swift:
内
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let url = url.standardizedURL
let query = url?.query
ViewController().labelToDisplayResult.text = query
return true;
}
不幸的是,我试图将 URL 的结果传递给实际标签的行给我这个错误:
EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
但是我可以肯定地在 App2 中拥有所有数据,因为我可以在调试器中看到它们的值:
url NSURL "app2://com.application.started?displayText=564315712437124375" 0x00007fa4e3426320
query String? "displayText=564315712437124375"
知道我为什么会收到此错误吗?
谢谢...
你的错误
ViewController().labelToDisplayResult.text = query
ViewController()
创建一个 ViewController
的新实例,而不是从 storyboard.I 加载的实例 猜测 labelToDisplayResult
是一个出口,所以它是零,所以你得到 EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
这是我平时处理openURL scheme的方式,需要考虑两种状态:
- 目标应用程序之前启动,所以当打开url发生时,目标应用程序处于后台或非活动状态
- 目标应用没有启动,所以当打开url时,目标应用根本就不是运行
在 Appdelegate 中
class AppDelegate: UIResponder, UIApplicationDelegate {
var openUrl:NSURL? //This is used when to save state when App is not running before the url trigered
var window: UIWindow?
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let url = url.standardizedURL
NSNotificationCenter.defaultCenter().postNotificationName("HANDLEOPENURL", object:url!)
self.openUrl = url
return true;
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}
}
然后在ViewController处理openURL
class ViewController: UIViewController {
@IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleOpenURL:", name:"HANDLEOPENURL", object: nil)
let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
if let url = delegate?.openUrl{
testLabel.text = url.description
delegate?.openUrl = nil
}
}
func handleOpenURL(notification:NSNotification){
if let url = notification.object as? NSURL{
testLabel.text = url.description
}
}
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self, name: "HANDLEOPENURL", object:nil)
}
}
我有两个测试应用程序:App1 和 App2。
App1 从文本字段中获取字符串并触发方法:
@IBAction func openApp(sender: AnyObject) {
let url1 = ("app2://com.application.started?displayText="+textToSend.text!)
let url2 = url1.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
UIApplication.sharedApplication().openURL(NSURL(string: url2!)!)
}
实际上打开了 App2,它只有标签,应该更改为通过 url 发送的文本,代码在 AppDelegate.swift:
内func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let url = url.standardizedURL
let query = url?.query
ViewController().labelToDisplayResult.text = query
return true;
}
不幸的是,我试图将 URL 的结果传递给实际标签的行给我这个错误:
EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
但是我可以肯定地在 App2 中拥有所有数据,因为我可以在调试器中看到它们的值:
url NSURL "app2://com.application.started?displayText=564315712437124375" 0x00007fa4e3426320
query String? "displayText=564315712437124375"
知道我为什么会收到此错误吗?
谢谢...
你的错误
ViewController().labelToDisplayResult.text = query
ViewController()
创建一个 ViewController
的新实例,而不是从 storyboard.I 加载的实例 猜测 labelToDisplayResult
是一个出口,所以它是零,所以你得到 EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
这是我平时处理openURL scheme的方式,需要考虑两种状态:
- 目标应用程序之前启动,所以当打开url发生时,目标应用程序处于后台或非活动状态
- 目标应用没有启动,所以当打开url时,目标应用根本就不是运行
在 Appdelegate 中
class AppDelegate: UIResponder, UIApplicationDelegate {
var openUrl:NSURL? //This is used when to save state when App is not running before the url trigered
var window: UIWindow?
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let url = url.standardizedURL
NSNotificationCenter.defaultCenter().postNotificationName("HANDLEOPENURL", object:url!)
self.openUrl = url
return true;
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}
}
然后在ViewController处理openURL
class ViewController: UIViewController {
@IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleOpenURL:", name:"HANDLEOPENURL", object: nil)
let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
if let url = delegate?.openUrl{
testLabel.text = url.description
delegate?.openUrl = nil
}
}
func handleOpenURL(notification:NSNotification){
if let url = notification.object as? NSURL{
testLabel.text = url.description
}
}
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self, name: "HANDLEOPENURL", object:nil)
}
}