Soru Bir temel hazırlık profilinin geliştirme veya dağıtım için programatik olarak nasıl algılandığı


Belirli bir temel hazırlık profilinin bir geliştirme profili veya dağıtım (adhoc veya uygulama mağazası) profili olup olmadığını öğrenmek istiyorum. Bunu tamamen programlı olarak yapmalıyım.

Adhoc vs appstore'u nasıl algıladığımı zaten biliyorum. Ve özellikle dev vs dağıtım ile ilgileniyorum.

Her bir profil türüne göre olan plistleri inceledim ve fark edilebilir bir fark bulamıyorum security cms -D -i #{@profilePath}). Ben de içine baktım openssl api ve bazı sertifika manipülasyonu için kullanıyorum.

Bu, özel bir xcode otomatik yapı sistemi içindir. Yapılandırma öncesi doğrulama işleminin bir parçası olarak, belirtilen profilin geliştirme için kullanılmamasını sağlamalıyım.

Bu mümkün mü? Eğer öyleyse, ikisi arasında programsal olarak nasıl ayırt edebilirim?

Herhangi bir fikir için şimdiden teşekkür ederiz!


25
2018-04-26 19:30


Menşei


Bu ilginç bir soru, +1.
Açıkçası, insanlar testflightapp.com .ipa dosyaları için yapıyoruz, ama ne yapıyorsun adhoc / appstore nasıl ayırt edeceğini bile bilmiyorum. XCode'un komut satırı araçlarının bir “tedarik profili tiftik aracı” içermesi gerektiğini düşünüyorum ve bu bizim için yapılmalı. Bu sadece zengin bir kullanıcı karmaşası kaynağı. Teşekkürler Apple. - Warren P
Merhaba Warren P, tüm bir adhv vs appstore profili tespit etmek için yapıyorum fyi varlığı için kontrol ediyor ProvisionedDevices profiletore profillerinin herhangi bir temel hazırlığa sahip olmadığı için, profilin plist'ini girin. Aptal olmayın, ama içinde çalıştığım sistem için amaca hizmet ediyor. Umarım bu yararlıdır. - Alfie Hanssen


Cevaplar:


Bu, aynı yapı için kendi yapı sistemlerimden birinde ele aldığım bir şeydi ... o zaman “iPhone Geliştirici Programı” nın 1. Gününe bir yolculuk yapalım. O zamanlar toplumun yanında olsaydın, alet zincirinin ... ... bugün olduğundan daha az dostça olduğunu söylersin.

AppStore veya AdHoc için inşa etmek istediğinizde bu meraklı entitlements.plist dosyasını yapmak zorunda kaldınız, o zaman bu dosyanın gövdesine bir blob XML yapıştırın. Daha sonra yapıyı çalıştırdınız ve o zaman sihir ortaya çıkmış gibi görünüyordunuz ve bu dosyanın yapısının varlığı, yapım işini yaptı, IPA'nızı manuel olarak oluşturmanıza ve her zamanki gibi işinize devam etmenize izin verdi. Şimdi birkaç yaş büyük ve umarız ki SDK'nın ilk günlerinden birazcık daha akıllıyız, sihirli XML blobunun aslında hiç bu kadar büyülü olmadığını anlamaya başladık - 'get-task-allow' anahtar, ikili kodun diğer işlemlere (belki de bir hata ayıklayıcı gibi) ikiliye eklenmesine izin vermesi gerektiğini belirten bir ayardır. Bir Uygulama Geliştirme Profili kullanarak uygulama imzalarken, bu anahtar 'true' olarak ayarlanacak (ve böylece LLDB'nin uygulamanıza eklemesine ve etkileşimde bulunmasına izin verecek) ... ve doğal olarak bir Dağıtım Temel Hazırlığı Profili kullanarak uygulama imzalarken bu anahtarın 'yanlış'.

Apple bazı güncellemeler verdi Teknik Not TN2250 XML'yi (ve yetkilendirmeleri genişleterek) Temel Hazırlık Profilleri'ni okuma hakkında:

güvenlik cms -D -i /path/to/the.app/embedded.mobileprovision

Bu, XML'yi Temel Hazırlık profilinde döndürecektir - buradan, "get-task-allow" için anahtar değer çiftini ayrıştırabilir ve bu değerden yararlanmak için, Temel Geliştirme Profilinin Geliştirme mi yoksa Dağıtım mı olduğunu belirleyin.

Doğrudan bize söyleyeceğimiz bir aracın olması güzel olurdu, bu yüzden ipuçları için profilden geçmek zorunda değiliz, ama aynı zamanda, en azından güvenilir, her ne kadar bir dolambaçlı yolumuz var? Çalışmadan önce bu ayrımı yapmak ve kullanamayacağımız bir yapı oluşturmak.

İyi şanslar ve daha fazla açıklamaya ihtiyacınız varsa veya başka sorularınız varsa bana bildirin.


18
2018-04-28 22:54



Büyük bir cevap, tam olarak aradığım şey, detaylı açıklama için teşekkür ederim! - Alfie Hanssen
Oldukça hoş geldiniz! ProvisionedDevices anahtarı hala iyi bir ikincil doğrulama ölçüsüdür; Onu sistemimde kullanmıyorum, ama kesinlikle yapabilirsin. - Bryan Musial


Toom'un kodunun daha kısa ve etkili bir sürümünü oluşturdum:

Kod parçacıklarını bu şekilde bir özgeçmişte saklayacağım, buradan daha güncel bir sürüm bulabilirsin: https://gist.github.com/steipete/7668246

static BOOL PSPDFIsDevelopmentBuild(void) {
#if TARGET_IPHONE_SIMULATOR
return YES;
#else
static BOOL isDevelopment = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // There is no provisioning profile in AppStore Apps.
    NSData *data = [NSData dataWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"embedded" ofType:@"mobileprovision"]];
    if (data) {
        const char *bytes = [data bytes];
        NSMutableString *profile = [[NSMutableString alloc] initWithCapacity:data.length];
        for (NSUInteger i = 0; i < data.length; i++) {
            [profile appendFormat:@"%c", bytes[i]];
        }
        // Look for debug value, if detected we're a development build.
        NSString *cleared = [[profile componentsSeparatedByCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] componentsJoinedByString:@""];
        isDevelopment = [cleared rangeOfString:@"<key>get-task-allow</key><true/>"].length > 0;
    }
});
return isDevelopment;
#endif
}

21
2017-11-26 23:35





Bryan Musial'ın büyük cevabına dayanarak, çalışma zamanında doğrudan uygulamadan "get-task-allow" komutunu kontrol etmenizi sağlayan bir kod yazdım. Benim durumumda, yalnızca hata ayıklama uygulamalarında oturum açmak için bu boolean kullanıyorum:

+ (BOOL)isDevelopmentApp
{
    // Special case of simulator
    if (isSimulator)
    {
        return YES;
    }

    // There is no provisioning profile in AppStore Apps
    NSString *profilePath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];

    // Check provisioning profile existence
    if (profilePath)
    {
        // Get hex representation
        NSData *profileData = [NSData dataWithContentsOfFile:profilePath];
        NSString *profileString = [NSString stringWithFormat:@"%@", profileData];

        // Remove brackets at beginning and end
        profileString = [profileString stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""];
        profileString = [profileString stringByReplacingCharactersInRange:NSMakeRange(profileString.length - 1, 1) withString:@""];

        // Remove spaces
        profileString = [profileString stringByReplacingOccurrencesOfString:@" " withString:@""];

        // Convert hex values to readable characters
        NSMutableString *profileText = [NSMutableString new];
        for (int i = 0; i < profileString.length; i += 2)
        {
            NSString *hexChar = [profileString substringWithRange:NSMakeRange(i, 2)];
            int value = 0;
            sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
            [profileText appendFormat:@"%c", (char)value];
        }

        // Remove whitespaces and new lines characters
        NSArray *profileWords = [profileText componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSString *profileClearText = [profileWords componentsJoinedByString:@""];

        // Look for debug value
        NSRange debugRange = [profileClearText rangeOfString:@"<key>get-task-allow</key><true/>"];
        if (debugRange.location != NSNotFound)
        {
            return YES;
        }
    }

    // Return NO by default to avoid security leaks
    return NO;
}

9
2017-07-29 17:18



Uygulama Mağazası hakkındaki yorum için hiçbir ön hazırlık profilinin bulunmadığı için teşekkür ederiz. Gizemli bir çarpışmada hata ayıklamaya yardım ettim! - phatmann


@ Steipete'nin yanıtına göre Swift 3 için bir sürüm:

static func isDevelopmentProvisioningProfile() -> Bool {
#if IOS_SIMULATOR
    return true
#else
    // there will be no provisioning profile in AppStore Apps
    guard let fileName = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision") else {
        return false
    }

    let fileURL = URL(fileURLWithPath: fileName)
    // the documentation says this file is in UTF-8, but that failed
    // on my machine. ASCII encoding worked ¯\_(ツ)_/¯
    guard let data = try? String(contentsOf: fileURL, encoding: .ascii) else {
        return false
    }

    let cleared: String = data.components(separatedBy: .whitespacesAndNewlines).joined()
    return cleared.contains("<key>get-task-allow</key><true/>")
#endif
}

Meraklıysa, get-task-allow olduğu Bir hata ayıklayıcısını ve bunun gibi diğer işlemleri bağlayabilmeniz için yapının kullandığı bir bayrak - Yani bir dev yapı ya da hayır olup olmadığı için oldukça doğru.


4
2017-11-21 22:41