/** * iOS APNs DeviceToken 封装(原生插件:NetworkUtils-NetworkUtilsModule) * 对应原生方法:getDeviceTokenAsync、refreshDeviceTokenAsync */ // #ifdef APP-PLUS const pushNetworkModule = uni.requireNativePlugin('NetworkUtils-NetworkUtilsModule') // #endif /** * 读取当前缓存的 DeviceToken(最近一次 didRegisterForRemoteNotifications 写入本地) * @param {Record} options 透传给原生,可为 {} */ export function getDeviceToken(options = {}) { return new Promise((resolve, reject) => { // #ifdef APP-PLUS if (!pushNetworkModule || typeof pushNetworkModule.getDeviceTokenAsync !== 'function') { reject(new Error('NetworkUtils 原生插件不可用或未注册 getDeviceTokenAsync')) return } pushNetworkModule.getDeviceTokenAsync(Object.assign({ registerIfEmpty: true }, options || {}), (ret) => { if (ret && (ret.status === 'success' || ret.status === 'empty')) { resolve(ret) } else { reject(ret || new Error('getDeviceTokenAsync 返回异常')) } }) // #endif // #ifndef APP-PLUS resolve({ status: 'empty', deviceToken: '', hasToken: false, updatedAt: 0, message: '非 App-PLUS 环境' }) // #endif }) } /** * 触发重新向 APNs 注册(token 更新后由原生写入本地,再调用 getDeviceToken 读取) * @param {{ requestAuthorization?: boolean }} options requestAuthorization 默认 true;已授权后可传 false 避免重复弹权限逻辑 */ export function refreshDeviceTokenAsync(options = {}) { return new Promise((resolve, reject) => { // #ifdef APP-PLUS if (!pushNetworkModule || typeof pushNetworkModule.refreshDeviceTokenAsync !== 'function') { reject(new Error('NetworkUtils 原生插件不可用或未注册 refreshDeviceTokenAsync')) return } const opts = { requestAuthorization: options.requestAuthorization !== false } pushNetworkModule.refreshDeviceTokenAsync(opts, (ret) => { if (ret && ret.status === 'requested') { resolve(ret) } else if (ret && (ret.status === 'error' || ret.status === 'denied')) { reject(ret) } else { resolve(ret || {}) } }) // #endif // #ifndef APP-PLUS resolve({ status: 'skipped', message: '非 App-PLUS 环境' }) // #endif }) } /** * 先刷新注册再轮询读取(适合首次拿 token 或服务端判定失效后) */ export async function refreshDeviceTokenAndFetch(options = {}) { await refreshDeviceTokenAsync(options) // 授权弹窗关闭 + registerForRemoteNotifications 多为异步,适度拉长首次等待 await new Promise((r) => setTimeout(r, 900)) let last = await getDeviceToken() for (let i = 0; i < 25 && last.status === 'empty'; i++) { await new Promise((r) => setTimeout(r, 400)) last = await getDeviceToken() } return last }