App 间的通信方式

1、前言

  • iOS 系统是相对封闭的系统,App 各自在各自的沙盒(sandbox)中运行,每个 App 都只能读取 iPhone 上 iOS 系统为该应用程序程序创建的文件夹 AppData 下的内容,不能随意跨越自己的沙盒去访问别的 App 沙盒中的内容。

  • 所以 iOS 的系统中进行 App 间通信的方式也比较固定,常见的 App 间通信方式以及使用场景总结如下。

2、URL Scheme URL 协议

  • 这个是 iOS App 通信最常用到的通信方式,App1 通过 openURL 的方法跳转到 App2,并且在 URL 中带上想要的参数,有点类似 http 的 get 请求那样进行参数传递,这种方式是使用最多的最常见的。

  • 使用方法也很简单,只需要源 App1 在 info.plist 中配置协议白名单 LSApplicationQueriesSchemes,指定目标 App2 的 scheme。

  • 然后在目标 App2 的 info.plist 中配置好 URL types,表示该 App 接受何种 URL scheme 的唤起。

    • 或者在 TARGETS -> info 中设置。

  • 在源 App1 执行跳转方法中实现下面方法,进行跳转通信

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // testApp2 为在 App2 中设置的协议 scheme
    NSURL *url = [NSURL URLWithString:@"testApp2://"];

    // 判断能否跳转到 App2
    if ([[UIApplication sharedApplication] canOpenURL:url]) {

    // 跳转到 App2
    [[UIApplication sharedApplication] openURL:url];

    } else {
    NSLog(@"没有安装应用");
    }
  • 典型的使用场景就是各开放平台 SDK 的分享功能,如分享到微信朋友圈微博等,或者是支付场景。比如从滴滴打车结束行程跳转到微信进行支付。

3、Keychain 钥匙串

  • iOS 系统的 Keychain 是一个安全的存储容器,它本质上就是一个 sqllite 数据库,它的位置存储在 /private/var/Keychains/keychain-2.db,不过它所保存的所有数据都是经过加密的,可以用来为不同的 App 保存敏感信息,比如用户名,密码等。iOS 系统自己也用 keychain 来保存 VPN 凭证和 WiFi 密码。它是独立于每个 App 的沙盒之外的,所以即使 App 被删除之后,Keychain 里面的信息依然存在。

  • 基于安全和独立于 App 沙盒的两个特性,Keychain 主要用于给 App 保存登录和身份凭证等敏感信息,这样只要用户登录过,即使用户删除了 App 重新安装也不需要重新登录。

  • 那 Keychain 用于 App 间通信的一个典型场景也和 App 的登录相关,就是统一账户登录平台。使用同一个账号平台的多个 App,只要其中一个 App 用户进行了登录,其他 App 就可以实现自动登录不需要用户多次输入账号和密码。一般开放平台都会提供登录 SDK,在这个 SDK 内部就可以把登录相关的信息都写到 keychain 中,这样如果多个 App 都集成了这个 SDK,那么就可以实现统一账户登录了。

  • Keychain 的使用比较简单,使用 iOS 系统提供的类 KeychainItemWrapper,并通过 keychain access groups 就可以在应用之间共享 keychain 中的数据的数据了。

  • 也可以使用 Keychain 的第三方框架 SSKeychain/SAMKeychain

    1
    2
    3
    4
    5
    6
    7
    8
    // 存储密码
    [SSKeychain setPassword:@"password" forService:[NSBundle mainBundle].bundleIdentifier account:@"username"];

    // 读取密码
    NSString *password = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier account:@"username"];

    // 删除密码
    [SSKeychain deletePasswordForService:[NSBundle mainBundle].bundleIdentifier account:@"username"];

4、UIPasteboard 剪切板

  • 顾名思义,UIPasteboard 是剪切板功能,因为 iOS 的原生控件 UITextField、UITextView、UIWebView,我们在使用时如果长按,就会出现复制、剪切、选中、全选、粘贴等功能,这个就是利用了系统剪切板功能来实现的。而每一个 App 都可以去访问系统剪切板,所以就能够通过系统剪贴板进行 App 间的数据传输了。

  • UIPasteboard 的使用很简单。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 创建系统级剪切板
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];

    // 忘系统剪切板中写入淘宝口令
    pasteboard.string = @"复制这条信息,打开 手机淘宝 即可看到【天猫 天天搞机】¥ AAJOjvII ¥";

    // 淘宝 App 从后台切换到前台时,从系统剪切板中读取淘宝口令进行显示
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"淘宝口令"
    message:pasteboard.string
    delegate:nil
    cancelButtonTitle:@"取消"
    otherButtonTitles:nil];
    [alert show];
  • UIPasteboard 典型的使用场景就是淘宝跟微信、QQ 的链接分享。由于腾讯和阿里的公司战略,腾讯在微信和 QQ 中都屏蔽了淘宝的链接。那如果淘宝用户想通过 QQ 或者微信跟好友分享某个淘宝商品,怎么办呢?阿里的工程师就巧妙的利用剪贴板实现了这个功能。首先淘宝 App 中将链接自定义成淘口令,引导用户进行复制,并去 QQ 好友对话中粘贴。然后 QQ 好友收到消息后再打开自己的淘宝 App,淘宝 App 每次从后台切到前台时,就会检查系统剪切板中是否有淘口令,如果有淘口令就进行解析并跳转到对于的商品页面。

  • 先复制淘口令到剪切板。

  • 再把剪切板中的内容粘贴到微信发给微信好友。

  • 微信好友把淘口令复制到淘宝中,就可以打开好友分享的淘宝链接了。

5、UIDocumentInteractionController 文档共享

  • UIDocumentInteractionController 主要是用来实现同设备上 App 之间的共享文档,以及文档预览、打印、发邮件和复制等功能。它的使用非常简单.

  • 首先通过调用它唯一的类方法 interactionControllerWithURL:,并传入一个 URL,为你想要共享的文件来初始化一个实例对象。然后设置 UIDocumentInteractionControllerDelegate,然后显示菜单和预览窗口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    NSURL *URL = [[NSBundle mainBundle] URLForResource:@"sample" withExtension:@"pdf"];

    if (URL) {

    // 初始化
    self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:URL];

    // 设置代理
    self.documentInteractionController.delegate = self;

    // 显示窗口预览 pdf
    [self.documentInteractionController presentPreviewAnimated:YES];
    }
  • 效果如下

6、local socket 本地 socket 连接

  • 这种方式不太常见,也是很容易被 iOS 开发者所忽略但是特别实用的一种方法。它的原理很简单,一个 App1 在本地的端口 port1234 进行 TCP 的 bind(绑定)和 listen(监听),另外一个 App2 在同一个端口 port1234 发起 TCP 的 connect(连接),这样就可以建立正常的 TCP 连接,进行 TCP 通信了,那么就想传什么数据就可以传什么数据了。

  • 这种方式最大的特点就是灵活,只要连接保持着,随时都可以传任何相传的数据,而且带宽足够大。它的缺点就是因为 iOS 系统在任意时刻只有一个 App 在前台运行,那么就要通信的另外一方具备在后台运行的权限,像导航或者音乐类 App。

  • 它是常用使用场景就是某个 App1 具有特殊的能力,比如能够跟硬件进行通信,在硬件上处理相关数据。而 App2 则没有这个能力,但是它能给 App1 提供相关的数据,这样 APP2 跟 App1 建立本地 socket 连接,传输数据到 App1,然后 App1 再把数据传给硬件进行处理。

文章目录
  1. 1. 1、前言
  2. 2. 2、URL Scheme URL 协议
  3. 3. 3、Keychain 钥匙串
  4. 4. 4、UIPasteboard 剪切板
  5. 5. 5、UIDocumentInteractionController 文档共享
  6. 6. 6、local socket 本地 socket 连接
隐藏目录