【问题标题】:How to get iOS appStoreReceiptURL into Base 64 Encoded String?如何将 iOS appStoreReceiptURL 转换为 Base 64 编码字符串?
【发布时间】:2013-09-26 07:01:44
【问题描述】:

我想使用 appStoreReceiptURL 查看某人购买了哪个版本的应用。我怎样才能把它变成一个字符串?

我正在通过从商店下载应用程序,然后从 Xcode 运行新版本的应用程序来对此进行测试。这是我尝试过的:

NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
NSLog(@"receiptUrl %@",[receiptUrl path]);
if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
        NSLog(@"exists");
         NSError *error;
         NSString *receiptString = [[NSString alloc] initWithContentsOfFile:[receiptUrl path] encoding:NSUTF8StringEncoding error:&error];
         if (receiptString == nil) {
              NSLog(@"Error: %@", [error localizedDescription]);
         } else {
             NSLog(@"Receipt: %@",receiptString);
        }

} else {
        NSLog(@"does not exist");
}

这是我得到的:

receiptUrl /var/mobile/Applications/E612F261-2D30-416E-BF82-F24xxxx8860/StoreKit/receipt
exists
Error: The operation couldn’t be completed. (Cocoa error 261.)

【问题讨论】:

    标签: ios nsstring app-store ios7


    【解决方案1】:

    我发现诀窍是将收据作为数据读取,然后从数据中进行 base 64 编码。如果它对其他人有帮助,这对我有用。还要感谢这个线程的 base 64 编码:Converting NSData to base64

    // this returns an NSDictionary of the app's store receipt, status=0 for good, -1 for bad
    - (NSDictionary *) getStoreReceipt:(BOOL)sandbox {
    
        NSArray *objects;
        NSArray *keys;
        NSDictionary *dictionary;
    
        BOOL gotreceipt = false;
    
        @try {
    
            NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    
            if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
    
                NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
    
                NSString *receiptString = [self base64forData:receiptData];
    
                if (receiptString != nil) {
    
                    objects = [[NSArray alloc] initWithObjects:receiptString, nil];
                    keys = [[NSArray alloc] initWithObjects:@"receipt-data", nil];
                    dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
    
                    NSString *postData = [self getJsonStringFromDictionary:dictionary];
    
                    NSString *urlSting = @"https://buy.itunes.apple.com/verifyReceipt";
                    if (sandbox) urlSting = @"https://sandbox.itunes.apple.com/verifyReceipt";
    
                    dictionary = [self getJsonDictionaryWithPostFromUrlString:urlSting andDataString:postData];
    
                    if ([dictionary objectForKey:@"status"] != nil) {
    
                        if ([[dictionary objectForKey:@"status"] intValue] == 0) {
    
                            gotreceipt = true;
    
                        }
                    }
    
                }
    
            }
    
        } @catch (NSException * e) {
            gotreceipt = false;
        }
    
        if (!gotreceipt) {
            objects = [[NSArray alloc] initWithObjects:@"-1", nil];
            keys = [[NSArray alloc] initWithObjects:@"status", nil];
            dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
        }
    
        return dictionary;
    }
    
    
    
    - (NSDictionary *) getJsonDictionaryWithPostFromUrlString:(NSString *)urlString andDataString:(NSString *)dataString {
        NSString *jsonString = [self getStringWithPostFromUrlString:urlString andDataString:dataString];
        NSLog(@"%@", jsonString); // see what the response looks like
        return [self getDictionaryFromJsonString:jsonString];
    }
    
    
    - (NSDictionary *) getDictionaryFromJsonString:(NSString *)jsonstring {
        NSError *jsonError;
        NSDictionary *dictionary = (NSDictionary *) [NSJSONSerialization JSONObjectWithData:[jsonstring dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];
        if (jsonError) {
           dictionary = [[NSDictionary alloc] init];
        }
        return dictionary;
    }
    
    
    - (NSString *) getStringWithPostFromUrlString:(NSString *)urlString andDataString:(NSString *)dataString {
        NSString *s = @"";
        @try {
            NSData *postdata = [dataString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
            NSString *postlength = [NSString stringWithFormat:@"%d", [postdata length]];
            NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
            [request setURL:[NSURL URLWithString:urlString]];
                [request setTimeoutInterval:60];
            [request setHTTPMethod:@"POST"];
            [request setValue:postlength forHTTPHeaderField:@"Content-Length"];
            [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
            [request setHTTPBody:postdata];
            NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
            if (data != nil) {
                s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            }
        }
        @catch (NSException *exception) { 
            s = @"";
        } 
        return s;
    }
    
    
    // from https://stackoverflow.com/questions/2197362/converting-nsdata-to-base64
    - (NSString*)base64forData:(NSData*)theData {
        const uint8_t* input = (const uint8_t*)[theData bytes];
        NSInteger length = [theData length];
        static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
        uint8_t* output = (uint8_t*)data.mutableBytes;
        NSInteger i;
        for (i=0; i < length; i += 3) {
            NSInteger value = 0;
            NSInteger j;
            for (j = i; j < (i + 3); j++) {
                value <<= 8;
    
                if (j < length) {
                    value |= (0xFF & input[j]);
                }
            }
            NSInteger theIndex = (i / 3) * 4;
            output[theIndex + 0] =                    table[(value >> 18) & 0x3F];
            output[theIndex + 1] =                    table[(value >> 12) & 0x3F];
            output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
            output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
        }
        return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    }
    

    【讨论】:

    • 缺少getJsonStringFromDictionary 的实现,但如果将其替换为:NSData *postData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&amp;error];
    • 更准确地说:getJsonStringFromDictionary -> NSError *error = nil; NSData *postData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error]; NSString *postString = @""; if (!postData) { NSLog(@"遇到错误:%@", error); } else { postString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]; }
    • 如果您遇到 21004 错误,请注意,不要忘记发送您的应用程序共享机密...就像这样 NSString *password = @"your shared secret string"; objects = [[NSArray alloc] initWithObjects:receiptString, password, nil]; keys = [[NSArray alloc] initWithObjects:@"receipt-data", @"password", nil];
    • 你好@Tom,如果我们的服务器正确,应该使用这种方法吗?
    【解决方案2】:

    这是我使用的代码:

    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
    
    NSString *encReceipt = [receiptData base64EncodedStringWithOptions:0];
    

    我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      Cocoa 错误 261 是 NSFileReadInapplicableStringEncodingError

      您尝试过NSASCIIStringEncoding,而不是尝试以UTF8 格式读取文件?

      NSString *receiptString =
          [[NSString alloc] initWithContentsOfFile:[receiptUrl path] 
                                          encoding:NSASCIIStringEncoding
                                             error:&error];
      

      此外,鉴于您不确定文件的实际编码,您可以使用以下内容而不是猜测。:

      NSStringEncoding *encoding = nil;
      NSString *receiptString =
          [NSString stringWithContentsOfFile:[receiptUrl path]
                                usedEncoding:&encoding
                                       error:NULL]; 
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-09
      • 2018-01-22
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2021-09-19
      相关资源
      最近更新 更多