9

定期的にアドホック配布方法でテスターに​​渡すアプリがあります。これらのテスターの何人かは「すぐに」、プロビジョニング プロファイルと四半期ごとの有効期限について十分に理解しており、(私が忘れた場合) テスト用に新しいバージョンを再構築するように私に促すことができます。

しかし、一部のユーザーは、iOS レベルのリマインダーをおそらく却下しているにもかかわらず、常に実行が停止するところまで到達し、それについて愚痴をこぼしたりうめいたりするようです。

私の質問は、プログラムで実行時に有効期限を取得し、独自の「アプリ内」アラートまたはシステム通知を実行して、新しいバージョンをプルダウンするように通知することはできますか?

4

5 に答える 5

8

あなたは次のようなものを探しています

"<key>ExpirationDate</key><date>2014-12-06T00:26:10Z</date>" in [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]

しかし、そこにたどり着くのは簡単ではありません!このコードは改善される可能性があり、その一部は他のスタックオーバーフローの投稿に基づいていました。注: もう 1 つのオプションは、item plist と /plist の間のすべてを ...a plist (辞書) にロードすることです。しかし、私たちはすでにそこにいるので、手で兄弟を見つけるだけです.

- (NSString*) getExpiry{

    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]];

        //There must be a better word to search through this as a structure! Need 'date' sibling to <key>ExpirationDate</key>, or use regex
        BOOL sibling = false;
        for (NSString* word in profileWords){
            if ([word isEqualToString:@"<key>ExpirationDate</key>"]){
                NSLog(@"Got to the key, now need the date!");
                sibling = true;
            }
            if (sibling && ([word rangeOfString:@"<date>"].location != NSNotFound)) {
                NSLog(@"Found it, you win!");
                NSLog(@"Expires: %@",word);
                return word;
            }
        }

    }

    return @"";
}
于 2014-01-08T20:56:36.393 に答える
4

迅速なバージョン:

// Returns `nil` if it fails
private func getProvisioningProfileExpirationDateAsString() -> String? {
    guard
        let profilePath = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision"),
        let profileData = try? Data(contentsOf: URL(fileURLWithPath: profilePath)),
        // Note: We use `NSString` instead of `String`, because it makes it easier working with regex, ranges, substring etc.
        let profileNSString = NSString(data: profileData, encoding: String.Encoding.ascii.rawValue)
        else {
        print("WARNING: Could not find or read `embedded.mobileprovision`. If running on Simulator, there are no provisioning profiles.")
        return nil
    }


    // NOTE: We have the `[\\W]*?` check to make sure that variations in number of tabs or new lines in the future does not influence the result.
    guard let regex = try? NSRegularExpression(pattern: "<key>ExpirationDate</key>[\\W]*?<date>(.*?)</date>", options: []) else {
        print("Warning: Could not create regex.")
        return nil
    }

    let regExMatches = regex.matches(in: profileNSString as String, options: [], range: NSRange(location: 0, length: profileNSString.length))

    // NOTE: range `0` corresponds to the full regex match, so to get the first capture group, we use range `1`
    guard let rangeOfCapturedGroupForDate = regExMatches.first?.range(at: 1) else {
        print("Warning: Could not find regex match or capture group.")
        return nil
    }

    let dateAsString = profileNSString.substring(with: rangeOfCapturedGroupForDate)
    return dateAsString
}
于 2018-09-20T16:08:37.493 に答える