从另一个应用程序中启动应用程序(iPhone)

182

在另一个应用程序内启动任意iPhone应用程序,这是可能的吗? 例如 如果我想让用户按一个按钮并直接进入电话应用程序(关闭当前应用程序,打开电话应用程序)。

这种操作是否可行?我知道可以通过tel URL链接来进行电话呼叫,但我想只是启动电话应用程序而不拨打任何特定号码。

14个回答

84

正如Kevin所指出的,URL Scheme是应用程序之间通信的唯一方式。 因此,不,无法启动任意应用程序。

但是,只要它是苹果公司、您或其他开发人员注册了URL Scheme,就可以启动任何应用程序。 文档在这里:

为您的应用定义自定义URL方案

至于启动电话,看起来您的tel:链接需要在启动电话之前至少拨打三个数字。 因此,您不能只是进入应用程序而不拨打号码。


9
您可以使用UIApplication的- (BOOL)canOpenURL:(NSURL *)url方法来检查所需应用程序是否已安装。 - Willster
1
如果两个应用程序注册了相同的URL处理程序,然后调用该URL会发生什么?我知道在Android中,您将被呈现一个列表,以便您可以选择要运行的两个应用程序中的哪一个。iOS如何处理这种情况? - eggie5
4
注意:如果有多个第三方应用程序注册处理相同的URL方案,则目前没有确定哪个应用程序将获得该方案的过程。参考:http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/AdvancedAppTricks/AdvancedAppTricks.html - Futur
3
这是更新后的链接,其中提到了超过三分之一的第三方应用程序注册处理相同的URL方案的注释:Apple文档 - Sindri Jóelsson
1
又过时了。更新链接:https://developer.apple.com/documentation/uikit/inter-process_communication?language=objc - Dave Nottage

79

我发现编写一个可以打开另一个应用程序的应用程序很容易。

假设我们有两个应用程序,分别称为 FirstApp SecondApp 。当我们打开FirstApp时,我们希望能够通过点击按钮打开SecondApp。实现此目标的解决方案是:

  1. 在SecondApp中

    转到SecondApp的plist文件,并添加一个名为 URL Schemes 的字符串(当然,您也可以使用其他字符串)。

enter image description here

2. 在FirstApp中

创建一个具有以下操作的按钮:

- (void)buttonPressed:(UIButton *)button
{
  NSString *customURL = @"iOSDevTips://";

  if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customURL]])
  {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
  }
  else
  {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL error"
                              message:[NSString stringWithFormat:@"No custom URL defined for %@", customURL]
                              delegate:self cancelButtonTitle:@"Ok" 
                              otherButtonTitles:nil];
    [alert show];
  }

}

就这样了。现在,当您点击第一个应用程序中的按钮时,它应该打开第二个应用程序。


2
你可以在这里看到完整的解释:http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html - youssman
1
@Lee,我在关注你的帖子,Safari可以打开应用程序,但是另一个应用程序无法打开(按钮按下方法),否则块被执行,有什么问题可以请你帮忙吗? - srinivas n
请给我更多关于你的问题的细节。 - lee
2
无法使其工作的人,请在“FirstApp”的“Info.plist”中添加一个名为“LSApplicationQueriesSchemes”的字符串数组。然后添加您的应用程序想要打开的方案,在这种情况下,“Item 0”将是“iOSDevTips”。 - user5936834
1
请参见下面KIO的答案(https://dev59.com/cXRC5IYBdhLWcg3wD87r#33763449)。FirstApp需要将`LSApplicationQueriesSchemes`添加到其Info.plist中,以便能够打开SecondApp。 - John Erck
显示剩余3条评论

31

对于 iOS 8 之前的版本,lee 的回答是完全正确的。

在 iOS 9+ 中,你必须在 Info.plist 下的 LSApplicationQueriesSchemes 键(一个字符串数组)中白名单任何 App 想要查询的 URL scheme:

输入图像描述


2
最佳答案应该是@KIO和villy393之间的合并。 - Gustavo Barbosa

23

在Swift语言中

以防有人正在寻找快速的Swift复制和粘贴。

if let url = URL(string: "app://"), UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else if let itunesUrl = URL(string: appLink), UIApplication.shared.canOpenURL(itunesUrl) {
            UIApplication.shared.open(itunesUrl, options: [:], completionHandler: nil)
        }

17
为了让您能够从另一个应用程序打开您的应用程序,您需要在两个应用程序中进行更改。以下是使用Swift 3iOS 10更新的步骤: 1. 注册您要打开的应用程序 通过定义您的应用程序的自定义和唯一的URL方案来更新Info.plist

enter image description here

请注意,您的 scheme 名称应该是唯一的,否则如果您的设备上安装了另一个具有相同 URL scheme 名称的应用程序,则在运行时将确定打开哪个应用程序。
2. 在主应用程序中包含以前的 URL scheme 您需要使用 UIApplication 类的 canOpenURL: 方法指定应用程序要使用的 URL scheme。因此,请打开主应用程序的 Info.plist 并将其他应用程序的 URL scheme 添加到 LSApplicationQueriesSchemes 中。(在 iOS 9.0 中引入)

enter image description here

3. 实现打开你的应用程序的操作

现在一切都设置好了,所以你可以在主应用程序中编写代码来打开其他应用程序。代码应该像这样:

let appURLScheme = "MyAppToOpen://"

guard let appURL = URL(string: appURLScheme) else {
    return
}

if UIApplication.shared.canOpenURL(appURL) {

    if #available(iOS 10.0, *) {
        UIApplication.shared.open(appURL)
    }
    else {
        UIApplication.shared.openURL(appURL)
    }
}
else {
    // Here you can handle the case when your other application cannot be opened for any reason.
}

请注意,如果您想让已从AppStore安装的现有应用程序打开,这些更改需要新版本发布。如果您要打开已经发布到苹果AppStore的应用程序,则首先需要上传包含您URL方案注册的新版本。

1
这是正确的答案。我注意到仅添加“LSApplicationQueriesSchemes”并不起作用,还需要在info.plist中添加“URL Scheme”。 - Shailesh
这个答案是100%正确的。在 "if UIApplication.shared.canOpenURL(appURL)" 的 else 部分,你可以添加以下内容:let appStoreURL = URL(string: "https://apps.apple.com/app/app-name/id123456789") // 用实际的 App Store URL 替换 如果 appStoreURL 不为空的话,可以使用以下代码打开 App Store:UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil) - undefined

11

这里有一个关于从另一个应用程序发起应用程序的好教程:
iOS SDK: 使用URL Scheme
而且,不可能启动任意应用程序,只能启动已注册了URL Scheme的本机应用程序。


9
为了实现这个目标,我们需要在两个应用程序中添加几行代码。
App A: 您想从另一个应用程序打开的应用程序(源)。
App B: 您想要打开App A(目标)的应用程序。
App A的代码:
在App A的Plist中添加一些标签。 打开App A的Plist源并粘贴以下XML。
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.TestApp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>testApp.linking</string>
        </array>
    </dict>
</array>

App A的应用代理中 - 在这里获取回调。
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// You we get the call back here when App B will try to Open 
// sourceApplication will have the bundle ID of the App B
// [url query] will provide you the whole URL 
// [url query] with the help of this you can also pass the value from App B and get that value here 
}

现在来谈谈App B的代码。
如果您只想打开App A而没有任何输入参数。
-(IBAction)openApp_A:(id)sender{

    if(![[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"testApp.linking://?"]]){
         UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"App is not available!" message:nil delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];

        }
}

如果您想从应用程序B传递参数到应用程序A,则使用以下代码

-(IBAction)openApp_A:(id)sender{
    if(![[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"testApp.linking://?userName=abe&registered=1&Password=123abc"]]){
         UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"App is not available!" message:nil delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];

        }
}

注意:您也可以在Safari浏览器中只输入testApp.linking://?来打开应用程序。

7
你只能启动已注册URL方案的应用程序。然后,就像使用sms:打开短信应用程序一样,您将能够使用它们的URL方案打开应用程序。
文档中有一个非常好的示例称为LaunchMe,演示了这一点。
截至2017年11月6日,LaunchMe示例代码可用。

更新的答案。希望能有所帮助。 - lostInTransit
谢谢;你有没有加入iOS开发者家族聊天室呢? - Eenvincible

7
尝试以下代码可以帮助您从应用程序启动另一个应用程序:
注意:请将名称fantacy替换为实际应用程序名称。
NSString *mystr=[[NSString alloc] initWithFormat:@"fantacy://location?id=1"];
NSURL *myurl=[[NSURL alloc] initWithString:mystr];
[[UIApplication sharedApplication] openURL:myurl];

5
在Swift 4.1和Xcode 9.4.1中,我有两个应用程序:1)PageViewControllerExample和2)DelegateExample。现在我想要打开DelegateExample应用程序并与PageViewControllerExample应用程序一起使用。当我在PageViewControllerExample中点击打开按钮时,DelegateExample应用程序将被打开。为此,我们需要对两个应用程序的.plist文件进行一些更改。 步骤1 在DelegateExample应用程序中打开.plist文件并添加URL类型和URL方案。在这里,我们需要添加我们所需的名称,如“myapp”。

enter image description here

步骤2

在PageViewControllerExample应用程序中打开.plist文件并添加以下代码

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>myapp</string>
</array>

现在,当我们在PageViewControllerExample中点击按钮时,我们可以打开DelegateExample应用程序。
//In PageViewControllerExample create IBAction
@IBAction func openapp(_ sender: UIButton) {

    let customURL = URL(string: "myapp://")
    if UIApplication.shared.canOpenURL(customURL!) {

        //let systemVersion = UIDevice.current.systemVersion//Get OS version
        //if Double(systemVersion)! >= 10.0 {//10 or above versions
            //print(systemVersion)
            //UIApplication.shared.open(customURL!, options: [:], completionHandler: nil)
        //} else {
            //UIApplication.shared.openURL(customURL!)
        //}

        //OR

        if #available(iOS 10.0, *) {
            UIApplication.shared.open(customURL!, options: [:], completionHandler: nil)
        } else {
            UIApplication.shared.openURL(customURL!)
        }
    } else {
         //Print alert here
    }
}

1
太好了,这很有帮助。现在如何将参数从源应用程序传递到目标应用程序? - Vigneswaran A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接