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

如何向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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:04:10