【问题标题】:How to detect if an iOS app is running on an M1 mac?如何检测 iOS 应用程序是否在 M1 mac 上运行?
【发布时间】:2021-03-10 13:23:47
【问题描述】:

我在 App Store 上提供了一款 iOS 应用。随着 Apple M1 Mac 的推出,可以在 macOS 上运行 iOS 应用程序。我想防止我的应用在 macOS 上使用,例如通过在启动后抛出异常或稍后调用 exit(0)。

如何检测应用程序是否在 M1 Mac 上运行?

在一定程度上,iOS 应用在 Mac 上运行seem to report themselves as iPads,所以这就排除了一些常见的设备识别方式。

提供上下文的一些细节:

  1. 我已经从 App Store Connect 上的 Mac App Store 中删除了该应用。

  2. 该应用是针对触摸屏制作和优化的。当前版本在 macOS 上运行时会提供非常糟糕的用户体验。要使其成为一款出色的 Mac 应用程序,需要进行许多更改和大量努力。我没有任何计划,更不用说这样做的资源了。

  3. 从表面上看,这可能类似于“如何检测我的应用程序是否在越狱设备上运行?”的问题。从技术上讲,这可能是正确的,而且我知道通常不建议实施越狱检测来防止 IAP 黑客等。一个重要的区别是 Apple 正在积极尝试防止越狱并强烈阻止用户这样做,这似乎保持越狱社区相当小而且不是主流,但另一方面,Apple 显然希望在 Mac 上提供尽可能多的 iOS 应用程序。目前在 Mac 上运行 iOS 应用程序非常容易,即使 Mac App Store 中不提供这些应用程序。在MacRumors 和9to5mac 等流行的科技博客上有说明。我想确保至少阻止这种在 Mac 上运行应用程序的简单方法。

  4. 此应用程序中的许多实现细节是在假设该应用程序只能在用户不容易访问的 iOS 沙箱中运行的情况下开发的。现在,用户使用修改过的资源、用户默认设置或Application Support 等目录的内容(包括我认为始终不可变的文件)运行应用程序可能要容易得多。如果用户找到了访问应用程序中通常需要应用内购买或订阅的内容的方法,例如通过捏造.plists 或以意想不到的方式重命名资源文件,这将是真正的商业风险。

【问题讨论】:

  • 我没有你那么担心。您提供的两个链接 - 一个是 5 步流程,一个是 6 步流程(涉及使用 IAP 文件,这只是开始。对我来说?底线是(a)首先让您的应用程序在 iOS 设备上运行尽可能最好,例如使用自动布局或 SwiftUI,然后 (b) 让“买家”提防。是的,这 是 Apple 的一个漏洞,也许他们会处理它 - 但是真的吗?如果你必须的话?在你的 iOS 应用商店页面(我相信它也会出现在 MAS 上)添加一些内容,说明你在 Mac 上使用你的应用时不做任何承诺。
  • 这不仅仅是用户体验问题。我在问题中添加了 (4.) 以进行澄清。
  • 我发现一些应用程序使用唯一标识符(例如某些双因素身份验证器)将自己绑定到设备,即使侧载到 M1 mac 也无法运行。同样的过程可用于防止您的应用程序被移植到 M1 mac。

标签: ios macos macos-big-sur


【解决方案1】:

Apple 的框架允许您使用进程信息标志isiOSAppOnMac 来检测应用程序是否在 Mac 上作为 iOS 应用程序运行。

此标志在 iOS 14.0 中可用,因此需要封装以仅在这些版本上运行。请注意,由于版本 14.0 也是 Mac 上 iOS 的第一个版本,因此您可以放心地假设如果版本低于 14.0,则它不能在 Mac 上。

// Swift
var isiOSAppOnMac = false
if #available(iOS 14.0, *) {
    isiOSAppOnMac = ProcessInfo.processInfo.isiOSAppOnMac
}
print("\(isiOSAppOnMac ? "iOS app on Mac" : "not iOS on Mac")!")

或者如果你更喜欢 Objective-C:

// Objective-C
BOOL isiOSAppOnMac = false;
if (@available(iOS 14.0, *)) {
    isiOSAppOnMac = [NSProcessInfo processInfo].isiOSAppOnMac;
}
NSLog(@"%@", isiOSAppOnMac ? @"iOS app on Mac" : @"not iOS app on Mac");

参考: Apple: Running Your iOS Apps on macOS

【讨论】:

  • 哦,很好。一个简单的原生 API。我不知道为什么当我搜索解决方案时没有找到它。
【解决方案2】:

此代码还检查应用程序是否作为 Mac Catalyst 应用程序运行。

var isiOSAppOnMac: Bool = {
#if targetEnvironment(macCatalyst)
    return true
#else
    if #available(iOS 14.0, *) {
        return ProcessInfo.processInfo.isiOSAppOnMac
    } else {
        return false
    }
#endif
}()

【讨论】:

    【解决方案3】:

    最简单的方法:

    struct Environment {
      static let isSimulator: Bool = {
        #if arch(i386) || arch(x86_64)
        return true
        #else
        return ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] != nil
        #endif
      }()
    }
    

    用法:

    Environment.isSimulator
    

    【讨论】:

      【解决方案4】:

      您的问题有以下子问题。

      1. 如何不让我的 iOS 应用在 Mac 上可用?

      如果您希望将您的应用程序限制为只能在 iOS 设备上下载,而不能在 macOS 设备上下载,那么您可以在 App Store Connect 中为您的应用程序禁用 Mac 可用性。学习more

      1. 如何知道我的应用 iOS 是否在由 M1 提供支持的 macOS 下运行?

      您必须获取有关 CPU 的信息,并且这个问题已经被问过并且有一个很好的答案here

      【讨论】:

      • Re 1:我已经在我的问题中声明我禁用了 Mac 可用性。回复 2:在这种情况下,这些函数实际上返回了什么?我应该测试哪些标识符?
      • 如果有一台带 M1 的 Mac 来测试确切的 cpu 名称,那就太好了
      【解决方案5】:

      要检查应用程序是否在 Mac Apple Silicon(如 M1)上以 iOS 模式运行,您必须检查仅适用于 iOS 14+ 的新 var:

      目标-c:

      if (@available(iOS 14.0, *) && [NSProcessInfo processInfo].isiOSAppOnMac) {
          // on Mac
      }
      

      斯威夫特:

      if #available(iOS 14.0, *), ProcessInfo.processInfo.isiOSAppOnMac {
          // on Mac
      }
      

      【讨论】:

      • 这与已接受的答案完全相同。
      • 抱歉,没注意。但这只是一行。
      猜你喜欢
      • 2022-08-04
      • 2021-12-24
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      • 2011-06-12
      • 2020-10-25
      • 2015-01-30
      • 2015-10-31
      相关资源
      最近更新 更多