如何向PushNotificationManager传入动态字符串?附报错及代码
解决
-[__NSSingleObjectArrayI un_stringWithMaxLength:]崩溃问题 这个崩溃的核心原因很明确:你给UserNotifications框架传递了一个数组(__NSSingleObjectArrayI是单元素数组的类型),但该框架的方法期望接收的是字符串对象。un_stringWithMaxLength:是UNNotificationContent相关API内部用来处理字符串的方法,当它收到数组时,自然找不到对应的方法,直接抛出异常崩溃。
结合你的代码场景(从网络请求返回的responseObject里取数据传给PushNotificationManager),大概率是你在解析JSON时,误将数组类型的字段当作字符串直接传递给了通知相关的API。
具体解决步骤
1. 先确认JSON返回的结构
首先你需要明确后端返回的JSON里,你用来构建通知的字段(比如标题、内容)到底是什么类型。可以在网络请求的success回调里打印完整的responseObject:
NSLog(@"完整Promotion JSON: %@", responseObject);
看输出结果,比如你要的通知标题字段,是不是类似"title": ["新促销活动"]这种数组格式,而不是你预期的"title": "新促销活动"字符串格式。
2. 修正字段取值逻辑
如果目标字段确实是单元素数组,你需要先提取数组里的第一个元素作为字符串使用,而不是直接把数组传进去。举个例子:
// 假设你之前直接取字段的写法是这样的(错误示范) // NSString *notifyTitle = json_promotion[@"title"]; // 改成带类型判断的安全取值 id titleRawValue = json_promotion[@"title"]; NSString *notifyTitle = @""; // 默认空字符串兜底 if ([titleRawValue isKindOfClass:[NSArray class]]) { // 如果是数组,取第一个元素(确保数组非空) if ([titleRawValue count] > 0) { notifyTitle = [titleRawValue firstObject]; } } else if ([titleRawValue isKindOfClass:[NSString class]]) { // 如果本身就是字符串,直接用 notifyTitle = titleRawValue; }
然后把notifyTitle这个字符串传给PushNotificationManager对应的参数。
3. 给通知内容添加类型校验
在构造UNNotificationContent的时候,一定要做类型安全检查,避免因为JSON结构变动再次触发崩溃:
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; // 确保标题是字符串类型再赋值 if ([notifyTitle isKindOfClass:[NSString class]]) { content.title = notifyTitle; } // 通知内容字段同理处理 NSString *notifyBody = ...; // 同样做类型校验 if ([notifyBody isKindOfClass:[NSString class]]) { content.body = notifyBody; }
额外优化建议
- 建议使用JSON转模型的库(比如YYModel、MJExtension),提前定义模型类的字段类型,这样能自动帮你处理类型转换,减少手动取值的错误。
- 永远不要假设后端返回的JSON结构完全符合预期,对所有关键字段都做类型校验,是避免这类崩溃的好习惯。
内容的提问来源于stack exchange,提问作者Test 87
相关产品推荐
相关产品推荐

