Stripe STPCustomerDeserializer解析Customer JSON时id字段返回nil求助
首先要明确核心问题:你传入STPCustomerDeserializer(jsonResponse: data)的data不是Stripe API返回的原始JSON数据,而是Objective-C中NSDictionary的调试描述格式(就是你贴出来的那种用=分隔键值、;分隔字段的格式),这直接导致了JSON解析失败,进而触发stp_stringForKey返回nil。
为什么会出现这个问题?
看你贴的“返回的Customer数据结构”:
["customer": { "account_balance" = 0; address = "
"; balance = 0; ... id = "cus_***"; ... }]
这种格式是NSLog打印NSDictionary时的输出样式,完全不是标准JSON——标准JSON应该用:分隔键值、,分隔字段,比如:
{"customer": {"account_balance": 0, "address": null, "balance": 0, ... "id": "cus_***", ...}}
另外你贴的内容里还有中文引号“***”,这也会破坏JSON的合法性。
当STPCustomerDeserializer尝试解析这种非JSON格式的数据时,自然会抛出The response from Stripe failed to get parsed into valid JSON.的错误,后续从错误解析出的字典中拿id时,要么键不存在,要么值的类型不是NSString,最终返回nil。
怎么解决?
1. 确保传入的是Stripe返回的原始NSData
你需要直接传递网络请求获取到的原始响应数据,而不是解析后的字典,更不是字典的打印字符串。比如用URLSession请求的话:
NSURL *url = [NSURL URLWithString:@"https://api.stripe.com/v1/customers/..."]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"请求失败: %@", error); return; } // 直接用这个data传入STPCustomerDeserializer STPCustomerDeserializer *deserializer = [[STPCustomerDeserializer alloc] initWithJSONResponse:data]; STPCustomer *customer = deserializer.customer; if (customer) { NSLog(@"解析成功,customer id: %@", customer.stripeId); } else { NSLog(@"解析失败: %@", deserializer.error); } }]; [task resume];
2. 验证传入的data是否为合法JSON
如果不确定数据是否合法,可以先用NSJSONSerialization提前校验:
NSError *jsonError = nil; id parsedJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError]; if (jsonError) { NSLog(@"JSON解析失败,错误信息: %@", jsonError); // 打印原始数据的字符串形式,排查格式问题 NSString *rawString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"原始数据字符串: %@", rawString); } else { NSLog(@"校验通过,解析后的JSON: %@", parsedJSON); }
3. 避免不必要的数据转换
不要把NSDictionary通过description方法转成字符串再传入解析器——这会得到你贴的那种非JSON格式。如果必须传递字符串形式的JSON,要用NSJSONSerialization把字典转成标准JSON字符串:
// 假设你已经有了解析后的customerDict NSError *error = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:customerDict options:0 error:&error]; if (!error) { STPCustomerDeserializer *deserializer = [[STPCustomerDeserializer alloc] initWithJSONResponse:jsonData]; // ...后续处理 }
总结
你的问题本质是数据格式不匹配:解析器需要标准JSON数据,而你传入的是字典的调试输出文本。只要确保传入的是Stripe返回的原始NSData(或合法的JSON字符串转成的NSData),就能解决id返回nil的问题。
内容的提问来源于stack exchange,提问作者melon biceps

