如何将iOS appStoreReceiptURL转换为Base 64编码字符串?

时间:2013-09-20 19:27:33

标签: ios nsstring app-store ios7

我想使用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.)

3 个答案:

答案 0 :(得分:29)

我发现诀窍是将收据作为数据读取,然后根据数据对其进行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];
}

答案 1 :(得分:10)

这是我使用的代码:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];

NSString *encReceipt = [receiptData base64EncodedStringWithOptions:0];

我希望这会有所帮助。

答案 2 :(得分:0)

可可错误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];