本文总结了 Android 和 iOS 在集成 JPush 过程中会遇到的常见问题

一、Android 获取 SDK 版本失败

1.1 报错日志示例


E/JPush: [JPushGlobal] Get sdk version fail![获取sdk版本失败!]

E/JPush: [JPushGlobal] JPush .so file do not match JPush .jar file in the project, Failed to init JPush

该日志说明:jar 与 so 不匹配。获取 SDK 失败 则集成失败,极光其他操作均不能正常进行。

1.2 排查方案

  1. 仔细根据文档中的说明进行配置,点我查看文档

  2. libs 每个目录下的 so 文件名字一样,但是内容是不一样的,不能随意复制。

  3. 检查是否还有其他地方放了so文件

  4. 如果你只加入了一个 CPU 框架下的 so,那可能是由于你现在的手机不是该 CPU 框架,所以加载失败了,建议加入所有so 后再测试。

  5. 若依旧有问题,将工程目录的文件夹全部展开,提供你的完整配置截图,并以包名过滤日志,提供完整日志

  6. 特殊机型的问题需要提供 具体的机型与系统信息

  7. 如果是使用 cocos2dx 开发,需要把 SDK 的 so 文件放到 cocos2dx 的编译环境里面

1.3 Android Studio 的使用说明

  1. android studio 打包加载.so 两种方式:
  • 第一种,把 so 放在 module/src/main/jniLibs 里面,在 gradle 配置中不用指定。

  • 第二种,在 gradle 配置中指定文件夹 jniLibs.srcDirs = [‘libs’] ,把 so 放到指定的目录 [‘libs’] 中。

  • 请确认使用 其中一种方式只能选择一种,确保路径一一对应!清一下工程再重新运行测试。

  1. 使用 android studio 的 release 版本

二、iOS 获取不到 token

2.1 报错日志示例


JIGUANG | W - [JIGUANGClientController] Not get deviceToken yet. Maybe: your certificate not configured APNs? or current network is not so good so APNs registration failed? or there is no APNs register code? Please refer to JPush docs.

获取 token 操作与网络有一定关系,因此如果只是偶尔的报错,则可以认为是网络问题,可以忽略,只要实际的操作最终可以成功即可(可以取到 token 和 registrationID ,如果连续 5 次报错,没有获取到 token,那么请根据以下排查步骤进行

2.2 初步排查方案

  1. 检查你的 app 是否配置了apns 权限

  2. 确保你的 app 是运行在 ios 真机而非模拟器上,且通知中心中对应 app 的通知权限没有完全关闭( alert/sound/badge 至少有一个权限是打开的

  3. 检查网络状况,与 apple 的服务器的连接是通过 tcp 的 5223 端口连接,确认网络的对应端口是否可用,可通过下列命令来确认这点:


telnet 1-courier.push.apple.com 5223
  1. 在代码中可在以下两个函数中断点以确认 device token 的获取状态。

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
  • 如果 app 运行进入 didFailToRegisterForRemoteNotificationsWithError 则说明 app 的 APNS 权限问题或者 app 运行在模拟器,参考证书设置文档

  • 如果 app 运行进入 didRegisterForRemoteNotificationsWithDeviceToken 则说明运行正常,请确认你在此函数中的代码中有将 token 传递给 jpush 的调用:


[JPUSHService registerDeviceToken:deviceToken];
  • 如果以上两个 registerRemoteNotification 的函数都未进入, 请确认你的代码中有注册申请 apns 的函数调用:

[JPUSHService registerForRemoteNotificationTypes:];
  1. 如果上述情况都已确认且未进入第 4 步的任意回调函数,则可以判断无法获取 token 的原因在于设备与 apple 的网络连通性问题
  • 一个设备只有在未申请过 token 的情况下才会需要与 apple 的网络交互来获取 token,已经获取过某一环境 token 的设备在无网络的情况下也能获取到对应环境的 token(环境分为 开发/生产)

  • 这种情况下切换网络能够在大部分情况下解决此问题。

2.3 细节排查方案

  1. 使用 xcode 8 及以上版本注意打开 Push Notification 按钮

  2. 检查你的 pushconfig 里的 Appkey 与官网-应用信息中的 AppKey 是否一致

  3. Bundle ID 有 3 处需要检查是否一致:

  • 应用详情中的 Bundle ID ;

  • info.plist 中的 Bundle ID ;

  • profile 文件中的 AppID 对应的 Bundle ID

  1. xcode-buildsetting-codesigning 里的 provisions profile 后面是否是你创建的相应的 profile 文件名

  2. 代码中是不是多处获取 devicetoken(比如说使用环信),使用多个第三方服务,只需要一处获取 devicetoken 就可以了

  3. 换一个 iOS 设备进行测试如果可以,而这个不行,请去 Apple 账号下删掉 Devices 然后重新注册 Devices

  4. 如果使用的是 unity 插件,unity2017 可能把推送功能关闭了,手动在代码中打开:将 UNITY_REMOTE_NOTIFICATIONS 设为 1。

null

null

  1. 如果测试环境是 OK 的,打包后报错,检查打包后是否缺少这个文件 archived-expanded-entitlements.xcent
  • 此时可能还会报这个错误,参考本帖 ,开发者使用 cordova 插件时曾出现过如下日志:

No valid 'aps-environment' entitlement string found for application 'com.rccchina.ProjectLeads': (null).
  • 找到 TARGET -> Build Setting -> Code Signing Identity -> Code Signing Entitlements *****Entitle-release.plist 看看有没有 aps-environment 字段,没有补上,建议阅读本文 ,也可以从 demo 中找到 Entitlements.plist 拖入你自己的工程。

<plist version="1.0">

<dict>

<key>aps-environment</key>

<string>production</string>

</dict>

</plist>
  1. iOS 13 系统目前经过测试,系统本身可能存在问题,少部分手机会存在取不到 token 的问题,该问题 SDK 无法解决,大家可以用原生推送集成后测试是否可以取到 token,取不到就是系统的问题,可以尝试如下方案:
  • 给手机插入 SIM 卡后再测试

  • 卸载重装、重启 App、关机重启后测试

  • 生产环境的包测试

  • 换别的 iOS 13 系统的手机测试

三、部分手机无法集成的问题

根据测试,有些 rom 禁用第三方推送,导致JPush服务不能启动。目前发现的rom有:一加3和努比亚。

  1. 一加2手机的解决办法:在【管理中心】 关闭相互启动服务即可正常注册服务

  2. 努比亚可以升级到最新的SDK 努比亚点击无法跳转的问题点我

  3. 努比亚 Z11 在 JPush 3.1.6+JCore 1.2.5 上存在集成无法成功问题,升级即可解决。

四、Android 报错 The permission should be defined

4.1 报错日志示例


E/JIGUANG-JCore: [AndroidUtil] The permissoin is required - com.jpush.test.permission.JPUSH_MESSAGE

E/JIGUANG-JCore: [AndroidUtil] The permission should be defined - com.jpush.test.permission.JPUSH_MESSAGE

W/JIGUANG-JCore: [JCoreInterface] JCore init failed

此错误是没有正确的定义 permision

4.2 解决方案

请在 Androidmanifest 里面添加权限:


<permission

android:name="您应用的包名.permission.JPUSH_MESSAGE"

android:protectionLevel="signature" />

<uses-permission android:name="您应用的包名.permission.JPUSH_MESSAGE" />
  • 类似的问题请注意对比 SDK 包中的 example 文件夹下的 Androidmanifest 文件的内容,检查自己添加权限的完整性。

  • 若权限已添加依旧报错,请检查包名的准确性。

五、Android 报错 Execution failed for task ‘:app:processDebugManifest’

  1. 打开应用的 AndroidManifest.xml 然后在左下角切换到 merged manifest 视图,可以看到合并 manifest 时的错误

  2. 根据错误说明检查是否缺少某个权限、重复配置权限等,参照 demo 中的 Androidmanifest 配置

  3. 自动集成不需要再手动配置权限,请着重注意,以免出现重复配置报错

  4. 把第一点中获取到的完整的错误信息提供给官方进行分析。

六、iOS 报 jpush-extension-ios-xxx.a 与 jcore-ios-xxx.a 冲突

6.1 报错日志示例

集成 3.0.7 及以上版本的 iOS SDK 运行后报如下错误, jpush-extension-ios-xxx.a 与 jcore-ios-xxx.a 冲突


ld: warning: object file (/Users/rongyao/huangyq/48_sha/xwolves48/Program/client/frameworks/runtime-src/proj.ios_mac/Lib/jpush-extension-ios-1.1.1.a(JPushExtensionTCPSocket.o)) was built for newer iOS version (10.0) than being linked (8.0)

ld: warning: object file (/Users/rongyao/huangyq/48_sha/xwolves48/Program/client/frameworks/runtime-src/proj.ios_mac/Lib/jpush-extension-ios-1.1.1.a(JPushExtensionSRVResolver.o)) was built for newer iOS version (10.0) than being linked (8.0)

duplicate symbol __sisHostDomains in:

/Users/rongyao/huangyq/48_sha/xwolves48/Program/client/frameworks/runtime-src/proj.ios_mac/Lib/jpush-extension-ios-1.1.1.a(JPushExtensionSession.o)

/Users/rongyao/huangyq/48_sha/xwolves48/Program/client/frameworks/runtime-src/proj.ios_mac/Lib/jcore-ios-1.2.0.a(JPUSHAddressController.o)

ld: 1 duplicate symbol for architecture armv7

这代表你们没有按照要求将 extension 的文件引入到 Service Extentsion 工程中,而是放在了主工程。

6.2 解决方案

请务必参考 demo 配置,将 extension 的文件引入到 Service Extentsion 工程中,如下图,如果你不需要上报通知送达数,则可以删除 extension 相关的文件(在官网推送历史-详情中将无法看到 iOS 送达数)。

null

七、iOS 编译报错 Undefined symbols for architecture i386

7.1 报错日志示例


Undefined symbols for architecture i386:

"_OBJC_CLASS_$_JPUSHRegisterEntity", referenced from:

objc-class-ref in AppDelegate.o

"_kJPFNetworkDidReceiveMessageNotification", referenced from:

-[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o

"_OBJC_CLASS_$_JPUSHService", referenced from:

objc-class-ref in AppDelegate.o

ld: symbol(s) not found for architecture i386

clang: error: linker command failed with exit code 1 (use -v to see invocation)

iOS 若编译报错 Undefined symbols for architecture i386 是因为 3.0.0 及以上版本 JPush SDK 将不再支持处理器为 i386 的模拟器,支持真机

i386 的架构是指 iphone5 以及以前的 iphone cpu 架构,已经没有支持的价值了。

7.2 解决方案

  1. 使用真机测试

  2. 选择 6/6Plus、6s/6sPlus、7/7Plus 等处理器不属于 i386 的模拟器

  3. Build Settings 里的 Build Active Architecture Only 设置为YES,5s 的模拟器也可以运行

  4. 如果你在非 i386 架构的模拟器上运行也报错了,我们推测是由于你的构建环境支持了 i386 导致的

  • 下载 demo,看看是否能够运行,能运行就是你自己项目的问题,如果不能运行就是你整体环境的问题
  1. 如果是使用 ionic 请使用这个命令:

ionic cordova build ios --device

如果对你有帮助,点个赞呗 ლ(╹◡╹ლ)

不吹不黑,关注「常见问题」专栏可以解决你 90% 的问题 (ノ◕ω◕)ノଘ_ଘ

如果还有你想知道的问题没有总结方案,来评论区跟我交流交流吖