You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:15:01