Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if an iOS app is running on an M1 mac?

I offer an iOS app on the App Store. With the launch of Apple's M1 Macs it's possible to run iOS apps on macOS. I want to prevent that my app is used on macOS, for example by throwing an exception after launch or calling exit(0) at a later time.

How can I detect that the app is running on an M1 Mac?

To a certain extent, iOS apps running on Macs seem to report themselves as iPads1, so this rules out some common ways to identify the device.

Some details to provide context:

  1. I already removed the app from the Mac App Store on App Store Connect.

  2. The app is made and optimized for touch screens. The current version would offer a very bad user experience when run on macOS. It would require many changes and a lot of effort to make it a good Mac app. I don't have any plans, let alone the resources to do that.

  3. On the surface this might seem similar to the question "How can I detect if my app runs on a jailbroken device?". Technically, this might be correct, and I understand that it's generally not advisable to implement jailbreak detection to prevent IAP hacks etc. An important difference is that Apple is actively trying to prevent jailbreaks and strongly discourages users from doing so, which seems to keeps the jailbreak community rather small and off mainstream, but on the other hand, Apple obviously wants to have as many iOS apps as possible available on Macs. It's currently very easy to run iOS apps on Macs, even if they are not offered in the Mac App Store. There are instructions on popular tech blogs like MacRumors and 9to5mac. I want to make sure that at least this easy way to run the app on a mac is prevented.

  4. Many implementation details in this app have been developed under the assumption that the app will only ever run in an iOS sandbox that users don't have easy access to. Now, it's probably much easier for users to run the app with modified resources, user defaults or contents of directories like Application Support, including files that I assumed to be always immutable. If users find a way to access content in the app that usually requires in-app purchases or subscriptions, for example by fudging .plists or renaming resource files in an unexpected way, it's a real business risk.


1 At the time of the original post, M1 Macs appeared to report themselves via hw.machine as model identifier iPad8,6. A tweet that provided a few more details has since been removed.

like image 218
Theo Avatar asked Nov 27 '20 19:11

Theo


People also ask

Do iOS apps run on M1 Macs?

The M1 processors used in the latest Macs are based on technology first developed for the company's iPhone and iPad. (In fact, the current iPad Pro uses the same M1 processor.) Because of this, the M1 brings to the Mac the ability to run iPhone and iPad apps.

How do I test iOS apps on my Macbook?

Test your app in macOSWhen you open your iOS project in Xcode 12 or later, you have the option to build your app and run it directly in macOS. This option doesn't run your app in a Simulator; it runs it as an iOS App on Mac. You can then test whether your app's features work as expected.

How do I know if my app is native on M1 Mac?

In the System Report window, select Software -> Applications in the sidebar. In the Applications list that loads, look under the Kind column to see whether an app is a Universal binary or a non-native Intel executable.


2 Answers

Apple's framework allows you to detect if the app is running as an iOS app on Mac by using the process info flag isiOSAppOnMac.

This flag is available from iOS 14.0 and therefore needs to be encapsulated to only run on those versions. Note that since version 14.0 is also the first version for iOS on Mac, you can safely assume that it cannot be on a Mac if the version is prior 14.0.

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

Or if you prefer 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");

Reference: Apple: Running Your iOS Apps on macOS

like image 119
LGP Avatar answered Oct 13 '22 20:10

LGP


This code also checks if the app is running as a Mac Catalyst app.

var isiOSAppOnMac: Bool = {
#if targetEnvironment(macCatalyst)
    return true
#else
    if #available(iOS 14.0, *) {
        return ProcessInfo.processInfo.isiOSAppOnMac
    } else {
        return false
    }
#endif
}()
like image 2
rockdaswift Avatar answered Oct 13 '22 18:10

rockdaswift