我在一个只在SenTestCase对象中测试时似乎崩溃的函数遇到了麻烦.
我要做的是从NSData对象获取base64-Encoded String(实际上是一个序列化的JSON字典).
在下面的代码中实际发生的是NSJSONSerialization创建一个NSConcreteData对象然后崩溃 [dataFromDictionary base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]
返回的崩溃是test failure: -[NSConcreteData base64EncodedStringWithOptions:]: unrecognized selector sent to instance
.
(in my SenTestCase implementation)
-(NSString *)paramsAsString {
NSDictionary *storedParams = @{@"stringKeyTest":@"testValueString", @"dictionaryKeyTest":@{@"testDictKey":@"testDictValue"}, @"numberKeyTest":@1 };
NSError *error = nil;
BOOL paramCheck = [NSJSONSerialization isValidJSONObject:storedParams];
//paramCheck is true
NSData *dataFromDictionary = [NSJSONSerialization dataWithJSONObject:storedParams options:0 error:&error];
//dataFromDictionary is actually NSConcreteData
NSString *stringFromData = [dataFromDictionary base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
//should stringify NSData, actually crashes
return stringFromData; //never reached
}
Run Code Online (Sandbox Code Playgroud)
我一直在谷歌搜索和堆栈溢出,我的测试目标可能有一个依赖项或标头丢失.我只是无法理解那是什么.这些都不是基金会框架功能吗?
在-all-load
和-ObjC
标志也都在目标设定,发生同样的错误.
更新: 在写这篇文章时,我找到了这个bug的解决方案.保留这篇帖子给后人,以防我找到了一个不理想的解决方案.
原来SenTest是一个红鲱鱼.导致问题的实际原因是构建目标(在测试模拟器中为6.1,在我的开发设备上为7.0)实际上无法访问新制作的公共iOS 7的方法.
我在文档中遇到了这个base64EncodedStringWithOptions:
:
Although this method was only introduced publicly for iOS 7, it has existed since iOS 4
Run Code Online (Sandbox Code Playgroud)
由于我计划支持iOS 5及更高版本,我添加了自己的base64编码/解码实现(基于Matt Gallagher的实现),现在一切都很顺利.
这是向后不兼容的简单情况.一个很好的教训,要记住未来.
Rob*_*Rob 16
如您所述,base64EncodedStringWithOptions
是iOS 7方法.如果需要,您可以使用第三方base-64库,但Apple已公开以前的私有方法base64Encoding
,以便与旧iOS版本向后兼容.因此,您可以这样做:
NSString string;
if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
string = [data base64EncodedStringWithOptions:kNilOptions]; // iOS 7+
} else {
string = [data base64Encoding]; // pre iOS7
}
Run Code Online (Sandbox Code Playgroud)
并转换回来:
NSData *data;
if ([NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)]) {
data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions]; // iOS 7+
} else {
data = [[NSData alloc] initWithBase64Encoding:string]; // pre iOS7
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7403 次 |
最近记录: |