capacitor-jpush-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapacitorJpushCore.podspec +19 -0
- package/Package.swift +29 -0
- package/README.md +496 -0
- package/android/build.gradle +79 -0
- package/android/src/main/AndroidManifest.xml +60 -0
- package/android/src/main/kotlin/com/capacitor/jpush/core/JPush.kt +261 -0
- package/android/src/main/kotlin/com/capacitor/jpush/core/JPushPlugin.kt +431 -0
- package/android/src/main/kotlin/com/capacitor/jpush/core/JPushReceiver.kt +245 -0
- package/android/src/main/kotlin/com/capacitor/jpush/core/JPushService.kt +10 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +651 -0
- package/dist/esm/definitions.d.ts +100 -0
- package/dist/esm/definitions.js +27 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +95 -0
- package/dist/esm/web.js +179 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +224 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +227 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/JPushPlugin/JPushPlugin-Bridging-Header.h +4 -0
- package/ios/Sources/JPushPlugin/JPushPlugin.swift +524 -0
- package/ios/Sources/JPushPlugin/JPushWrapper.swift +241 -0
- package/package.json +90 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// JPushWrapper.swift
|
|
2
|
+
// Swift wrapper for JPush functionality
|
|
3
|
+
|
|
4
|
+
import Foundation
|
|
5
|
+
import UIKit
|
|
6
|
+
|
|
7
|
+
// Alias operation completion handler type
|
|
8
|
+
typealias JPushAliasCompletion = (Bool, Error?) -> Void
|
|
9
|
+
|
|
10
|
+
// UserDefaults key for saving launchOptions
|
|
11
|
+
private let kJPushLaunchOptionsKey = "JPushLaunchOptions"
|
|
12
|
+
|
|
13
|
+
class JPushWrapper: NSObject {
|
|
14
|
+
|
|
15
|
+
private static func showAlert(_ message: String) {
|
|
16
|
+
// Show native alert with launchOptions content for debugging
|
|
17
|
+
DispatchQueue.main.async {
|
|
18
|
+
let alertController = UIAlertController(title: "JPush", message: message, preferredStyle: .alert)
|
|
19
|
+
|
|
20
|
+
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
|
|
21
|
+
alertController.addAction(okAction)
|
|
22
|
+
|
|
23
|
+
// Get the current root view controller
|
|
24
|
+
if let rootViewController = UIApplication.shared.windows.first?.rootViewController {
|
|
25
|
+
rootViewController.present(alertController, animated: true, completion: nil)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static func initJPush(withAppKey appKey: String, channel: String?, production: Bool) {
|
|
31
|
+
|
|
32
|
+
JPUSHService.setup(withOption: nil, appKey: appKey, channel: channel, apsForProduction: production)
|
|
33
|
+
if !production {
|
|
34
|
+
JPUSHService.setDebugMode()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 初始化完成后清除保存的launchOptions
|
|
38
|
+
UserDefaults.standard.removeObject(forKey: kJPushLaunchOptionsKey)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get registration ID
|
|
43
|
+
* @return Registration ID
|
|
44
|
+
*/
|
|
45
|
+
static func registrationID() -> String {
|
|
46
|
+
return JPUSHService.registrationID()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Set alias
|
|
51
|
+
* @param alias Alias
|
|
52
|
+
* @param seq Sequence number, user-defined for operation identification
|
|
53
|
+
* @param completion Completion handler
|
|
54
|
+
*/
|
|
55
|
+
static func setAlias(_ alias: String, seq: Int? = nil, completion: @escaping JPushAliasCompletion) {
|
|
56
|
+
let sequence = seq ?? 0
|
|
57
|
+
JPUSHService.setAlias(alias, completion: { (iResCode, iAlias, sequence) in
|
|
58
|
+
if iResCode == 0 {
|
|
59
|
+
completion(true, nil)
|
|
60
|
+
} else {
|
|
61
|
+
let error = NSError(domain: "JPush", code: Int(iResCode), userInfo: [NSLocalizedDescriptionKey: "Alias setting failed, error code: \(iResCode)"])
|
|
62
|
+
completion(false, error)
|
|
63
|
+
}
|
|
64
|
+
}, seq: sequence)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Delete alias
|
|
69
|
+
* @param seq Sequence number, user-defined for operation identification
|
|
70
|
+
* @param completion Completion handler
|
|
71
|
+
*/
|
|
72
|
+
static func deleteAlias(seq: Int? = nil, completion: @escaping JPushAliasCompletion) {
|
|
73
|
+
let sequence = seq ?? 0
|
|
74
|
+
JPUSHService.deleteAlias({ (iResCode, iAlias, sequence) in
|
|
75
|
+
if iResCode == 0 {
|
|
76
|
+
completion(true, nil)
|
|
77
|
+
} else {
|
|
78
|
+
let error = NSError(domain: "JPush", code: Int(iResCode), userInfo: [NSLocalizedDescriptionKey: "Alias deletion failed, error code: \(iResCode)"])
|
|
79
|
+
completion(false, error)
|
|
80
|
+
}
|
|
81
|
+
}, seq: sequence)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Set tags
|
|
86
|
+
* @param tags Tags to set
|
|
87
|
+
* @param seq Sequence number, user-defined for operation identification
|
|
88
|
+
* @param completion Completion handler
|
|
89
|
+
*/
|
|
90
|
+
static func setTags(_ tags: Set<String>, seq: Int? = nil, completion: @escaping JPushAliasCompletion) {
|
|
91
|
+
let sequence = seq ?? 0
|
|
92
|
+
JPUSHService.setTags(tags, completion: { (iResCode, iTags, sequence) in
|
|
93
|
+
if iResCode == 0 {
|
|
94
|
+
completion(true, nil)
|
|
95
|
+
} else {
|
|
96
|
+
let error = NSError(domain: "JPush", code: Int(iResCode), userInfo: [NSLocalizedDescriptionKey: "Tags setting failed, error code: \(iResCode)"])
|
|
97
|
+
completion(false, error)
|
|
98
|
+
}
|
|
99
|
+
}, seq: sequence)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Add tags
|
|
104
|
+
* @param tags Tags to add
|
|
105
|
+
* @param seq Sequence number, user-defined for operation identification
|
|
106
|
+
* @param completion Completion handler
|
|
107
|
+
*/
|
|
108
|
+
static func addTags(_ tags: Set<String>, seq: Int? = nil, completion: @escaping JPushAliasCompletion) {
|
|
109
|
+
let sequence = seq ?? 0
|
|
110
|
+
JPUSHService.addTags(tags, completion: { (iResCode, iTags, sequence) in
|
|
111
|
+
if iResCode == 0 {
|
|
112
|
+
completion(true, nil)
|
|
113
|
+
} else {
|
|
114
|
+
let error = NSError(domain: "JPush", code: Int(iResCode), userInfo: [NSLocalizedDescriptionKey: "Tags adding failed, error code: \(iResCode)"])
|
|
115
|
+
completion(false, error)
|
|
116
|
+
}
|
|
117
|
+
}, seq: sequence)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Delete tags
|
|
122
|
+
* @param tags Tags to delete
|
|
123
|
+
* @param seq Sequence number, user-defined for operation identification
|
|
124
|
+
* @param completion Completion handler
|
|
125
|
+
*/
|
|
126
|
+
static func deleteTags(_ tags: Set<String>, seq: Int? = nil, completion: @escaping JPushAliasCompletion) {
|
|
127
|
+
let sequence = seq ?? 0
|
|
128
|
+
JPUSHService.deleteTags(tags, completion: { (iResCode, iTags, sequence) in
|
|
129
|
+
if iResCode == 0 {
|
|
130
|
+
completion(true, nil)
|
|
131
|
+
} else {
|
|
132
|
+
let error = NSError(domain: "JPush", code: Int(iResCode), userInfo: [NSLocalizedDescriptionKey: "Tags deletion failed, error code: \(iResCode)"])
|
|
133
|
+
completion(false, error)
|
|
134
|
+
}
|
|
135
|
+
}, seq: sequence)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Clean all tags
|
|
140
|
+
* @param seq Sequence number, user-defined for operation identification
|
|
141
|
+
* @param completion Completion handler
|
|
142
|
+
*/
|
|
143
|
+
static func cleanTags(seq: Int? = nil, completion: @escaping JPushAliasCompletion) {
|
|
144
|
+
let sequence = seq ?? 0
|
|
145
|
+
JPUSHService.cleanTags({ (iResCode, iTags, sequence) in
|
|
146
|
+
if iResCode == 0 {
|
|
147
|
+
completion(true, nil)
|
|
148
|
+
} else {
|
|
149
|
+
let error = NSError(domain: "JPush", code: Int(iResCode), userInfo: [NSLocalizedDescriptionKey: "Tags cleaning failed, error code: \(iResCode)"])
|
|
150
|
+
completion(false, error)
|
|
151
|
+
}
|
|
152
|
+
}, seq: sequence)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Request notification authorization
|
|
157
|
+
* @param completion Completion handler with authorization status
|
|
158
|
+
*/
|
|
159
|
+
static func requestNotificationAuthorization(completion: @escaping (Bool) -> Void) {
|
|
160
|
+
JPUSHService.requestNotificationAuthorization { status in
|
|
161
|
+
let granted = status == .statusAuthorized || status == .statusProvisional
|
|
162
|
+
completion(granted)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Handle remote notification
|
|
168
|
+
* @param userInfo Notification content
|
|
169
|
+
*/
|
|
170
|
+
static func handleRemoteNotification(_ userInfo: [AnyHashable: Any]) {
|
|
171
|
+
JPUSHService.handleRemoteNotification(userInfo)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Register device token
|
|
176
|
+
* @param deviceToken Device token
|
|
177
|
+
*/
|
|
178
|
+
static func registerDeviceToken(_ deviceToken: Data) {
|
|
179
|
+
JPUSHService.registerDeviceToken(deviceToken)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Set unread badge count
|
|
184
|
+
* @param badge Badge count, 0 means clear badge
|
|
185
|
+
*/
|
|
186
|
+
static func setBadge(_ badge: Int) {
|
|
187
|
+
|
|
188
|
+
JPUSHService.setBadge(badge)
|
|
189
|
+
|
|
190
|
+
if #available(iOS 16.0, *) {
|
|
191
|
+
UNUserNotificationCenter.current().setBadgeCount(badge)
|
|
192
|
+
} else if (badge == 0) {
|
|
193
|
+
clearBadgeOnlyKeepNotifications()
|
|
194
|
+
} else {
|
|
195
|
+
UIApplication.shared.applicationIconBadgeNumber = badge
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private static func clearBadgeOnlyKeepNotifications() {
|
|
200
|
+
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
|
|
201
|
+
let center = UNUserNotificationCenter.current()
|
|
202
|
+
|
|
203
|
+
notifications.forEach { notification in
|
|
204
|
+
// 关键修复:将只读的 UNNotificationContent 转为可变的 UNMutableNotificationContent
|
|
205
|
+
guard let mutableContent = notification.request.content.mutableCopy() as? UNMutableNotificationContent else {
|
|
206
|
+
print("❌ 无法转换为可变通知内容")
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 现在可以正常修改 badge(可变对象的可写属性)
|
|
211
|
+
mutableContent.badge = 0
|
|
212
|
+
|
|
213
|
+
// 重新创建通知请求(用可变内容)
|
|
214
|
+
let newRequest = UNNotificationRequest(
|
|
215
|
+
identifier: notification.request.identifier, // 复用原ID,覆盖原通知
|
|
216
|
+
content: mutableContent,
|
|
217
|
+
trigger: nil
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
center.add(newRequest) { error in
|
|
221
|
+
if let error = error {
|
|
222
|
+
print("❌ 更新通知角标失败:\(error.localizedDescription)")
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let emptyContent = UNMutableNotificationContent() // 直接创建可变对象
|
|
228
|
+
emptyContent.badge = 0
|
|
229
|
+
let emptyRequest = UNNotificationRequest(
|
|
230
|
+
identifier: "clear_badge_only",
|
|
231
|
+
content: emptyContent,
|
|
232
|
+
trigger: nil
|
|
233
|
+
)
|
|
234
|
+
center.add(emptyRequest) { _ in
|
|
235
|
+
center.removeDeliveredNotifications(withIdentifiers: ["clear_badge_only"])
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// JPUSHService.resetBadge()
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "capacitor-jpush-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "极光推送Capacitor插件,支持Android和iOS平台基本推送功能",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ionic",
|
|
7
|
+
"capacitor",
|
|
8
|
+
"plugin",
|
|
9
|
+
"native",
|
|
10
|
+
"android",
|
|
11
|
+
"ios",
|
|
12
|
+
"jpush",
|
|
13
|
+
"jiguang",
|
|
14
|
+
"core",
|
|
15
|
+
"极光推送",
|
|
16
|
+
"push notification",
|
|
17
|
+
"推送通知"
|
|
18
|
+
],
|
|
19
|
+
"main": "dist/plugin.cjs.js",
|
|
20
|
+
"module": "dist/esm/index.js",
|
|
21
|
+
"types": "dist/esm/index.d.ts",
|
|
22
|
+
"unpkg": "dist/plugin.js",
|
|
23
|
+
"files": [
|
|
24
|
+
"android/src/main/",
|
|
25
|
+
"android/build.gradle",
|
|
26
|
+
"dist/",
|
|
27
|
+
"ios/Sources",
|
|
28
|
+
"Package.swift",
|
|
29
|
+
"CapacitorJpushCore.podspec"
|
|
30
|
+
],
|
|
31
|
+
"author": "hybrid",
|
|
32
|
+
"maintainers":["hybrid"],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/hybrid/capacitor-jpush-core.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/hybrid/capacitor-jpush-core/issues"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
43
|
+
"verify:ios": "xcodebuild -scheme capacitor-jpush-core -destination generic/platform=iOS",
|
|
44
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
45
|
+
"verify:web": "npm run build",
|
|
46
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
47
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
48
|
+
"eslint": "eslint . --ext ts",
|
|
49
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
|
|
50
|
+
"swiftlint": "node-swiftlint",
|
|
51
|
+
"docgen": "docgen --api JPushPlugin --output-readme README.md --output-json dist/docs.json",
|
|
52
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
53
|
+
"clean": "rimraf ./dist",
|
|
54
|
+
"watch": "tsc --watch",
|
|
55
|
+
"prepublishOnly": "npm run build"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@capacitor/android": "^7.0.0",
|
|
59
|
+
"@capacitor/core": "^7.0.0",
|
|
60
|
+
"@capacitor/docgen": "^0.3.0",
|
|
61
|
+
"@capacitor/ios": "^7.0.0",
|
|
62
|
+
"@ionic/eslint-config": "^0.4.0",
|
|
63
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
64
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
65
|
+
"@types/node": "^22.0.0",
|
|
66
|
+
"eslint": "^8.57.0",
|
|
67
|
+
"prettier": "^3.4.2",
|
|
68
|
+
"prettier-plugin-java": "^2.6.6",
|
|
69
|
+
"rimraf": "^6.0.1",
|
|
70
|
+
"rollup": "^4.30.1",
|
|
71
|
+
"swiftlint": "^2.0.0",
|
|
72
|
+
"typescript": "^5.9.3"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@capacitor/core": ">=7.0.0"
|
|
76
|
+
},
|
|
77
|
+
"prettier": "@ionic/prettier-config",
|
|
78
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
79
|
+
"eslintConfig": {
|
|
80
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
81
|
+
},
|
|
82
|
+
"capacitor": {
|
|
83
|
+
"ios": {
|
|
84
|
+
"src": "ios"
|
|
85
|
+
},
|
|
86
|
+
"android": {
|
|
87
|
+
"src": "android"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|