2019年12月29日日曜日

ipaファイル内のembedded.mobileprovisionから有効期限(ExpirationDate)を読み込む

AdHocやEnterpriseでのリリースでは有効期限があるので、それを取り出し、ユーザーに見せるようにしていた。

embedded.mobileprovisionをNSDataで読み込み、NSStringに全変換してから、NSStringのメソッドで処理していたのだが、暗号化された文字コード以外の値が入っているため、SDK13ではクラッシュを招いてしまった。

反省して、NSPropertyListSerializationで処理する正しい方法に改めた。



-(NSString *)readExpiredDay
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
    if (!path) return @"NG";
    NSData *data = [NSData dataWithContentsOfFile:path];
    
    // plistを抽出
    NSRange start = [data rangeOfData:[@"<?xml" dataUsingEncoding:NSUTF8StringEncoding] options:NSDataSearchBackwards range:NSMakeRange(0, [data length])];
    NSRange end = [data rangeOfData:[@"</plist>" dataUsingEncoding:NSUTF8StringEncoding] options:NSDataSearchBackwards range:NSMakeRange(start.location, [data length] - start.location)];
    NSData *body = [data subdataWithRange:NSMakeRange(start.location, end.location + end.length - start.location)];
    
    // NSDictionaryに変換
    NSPropertyListFormat format;
    NSDictionary *dic = (NSDictionary *)[NSPropertyListSerialization propertyListWithData:body options:NSPropertyListMutableContainersAndLeaves format:&format error:nil];
    if (!dic) return @"NG";
    
    // ExpirationDateを検出
    NSDate *date = dic[@"ExpirationDate"];
    if (!date) return @"NG";

    // UTC->JST変換し文字列とする
    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    [fmt setDateFormat:@"yyyy/MM/dd"];
    [fmt setTimeZone:[NSTimeZone defaultTimeZone]];
    NSString *str = [fmt stringFromDate:date];
    
    if (!str) return @"NG";
    return str;
}

swift版のM.Ike様のコードを参考にしました。


0 件のコメント:

コメントを投稿