iOS序列化AVBase实例数组报Invalid type in JSON write错误如何解决
错误原因
NSJSONSerialization 仅支持系统原生的JSON合法类型(包括NSArray、NSDictionary、NSString、NSNumber、NSNull),自定义类实例不属于支持范围,哪怕类的所有属性都是合法JSON类型,也无法直接被序列化。
另外你原代码存在一个方法名调用错误:定义的初始化方法为initWithPortName:andUID:andPort:,调用时写成了initWithPortNumber:andUID:andPort:,运行时会触发找不到方法的异常,需要先修正。
解决方案
提供两种常用实现方案:
方案1:直接构造字典存入数组(适合简单场景)
不需要保留AVBase自定义类的情况下,直接将设备属性封装为字典存入数组,可直接被序列化:
NSMutableArray *myArray = [[NSMutableArray alloc] init]; AVAudioSession *session = AVAudioSession.sharedInstance; NSArray *outputs = [[session currentRoute] outputs]; for(AVAudioSessionPortDescription* output in outputs) { NSDictionary *item = @{ @"portName": output.portName ?: @"", @"uid": output.UID ?: @"", @"port": [output.portType description] ?: @"" }; [myArray addObject:item]; } NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
代码中?: @""是为了处理属性为空的情况,避免nil存入字典导致崩溃。
方案2:给AVBase新增转字典方法(适合需要保留自定义类的场景)
首先在AVBase的头文件新增转字典方法声明:
#import <AVFoundation/AVFoundation.h> NS_ASSUME_NONNULL_BEGIN @interface AVBase : NSObject @property NSString *portName; @property NSString *uid; @property NSString* port; - (id) initWithPortName:(NSString *)portName andUID:(NSString *)uid andPort:(AVAudioSessionPort)port; // 新增转字典方法 - (NSDictionary *)toDictionary; @end NS_ASSUME_NONNULL_END
在AVBase的实现文件补充方法实现:
@implementation AVBase - (id)initWithPortName:(NSString *)portName andUID:(NSString *)uid andPort:(AVAudioSessionPort)port { self = [super init]; if (self) { self.portName = portName; self.uid = uid; self.port = [port description]; } return self; } - (NSDictionary *)toDictionary { return @{ @"portName": self.portName ?: @"", @"uid": self.uid ?: @"", @"port": self.port ?: @"" }; } @end
序列化前将AVBase实例转为字典再存入数组即可:
NSMutableArray *myArray = [[NSMutableArray alloc] init]; AVAudioSession *session = AVAudioSession.sharedInstance; NSArray *outputs = [[session currentRoute] outputs]; for(AVAudioSessionPortDescription* output in outputs) { // 修正初始化方法名 AVBase* av = [[AVBase alloc] initWithPortName:output.portName andUID:output.UID andPort:output.portType]; [myArray addObject:[av toDictionary]]; } NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
内容的提问来源于stack exchange,提问作者Keselme
相关产品推荐
相关产品推荐

