This is from my app which is written in objc, you can easily rewrite these methods in swift if you’d like.
Check if provisioning profile exist. Apple strips this out when uploaded to the App Store but when sideloaded it remains
NSString *provisionPath = [[NSBundle mainBundle]] pathForResource:@"embedded" ofType:@"mobileprovision"];
if (nil != provisionPath) {
// app is cracked..
}
Verify the apps bundleIdentifer. When sideloading apps on newer iOS versions it will modify the bundleidentifier
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
if(![@"com.yourcompany.yourapp" isEqualToString:bundleIdentifier]) {
// app is cracked
}
Check for CydiaSubstrate or Substitute. Usually when sideloading apps you will also either inject CydiaSubstrate or Substitute for tweak compatibility.
int max = _dyld_image_count();
for (int i = 0; i < max; i++) {
const char *name = _dyld_get_image_name(i);
NSString *names = [NSString stringWithUTF8String:name];
if (([names containsString:@"CydiaSubstrate"] || [names containsString:@"substitute])) {
// app could be cracked or user is just jailbroken
}
For more methods like checking the encryption state you should check out this thread: How do I detect if an app has been cracked without examining the SignerIdentity? and also don’t think that these methods can’t be broken because they are quite trivial but a good start to protecting your app (: