A Skip framework for cross-platform push notifications
on iOS and Android without depending on the com.google.firebase:firebase-messaging library.
- iOS: Uses the native
UserNotificationsframework and APNs. - Android: Interfaces directly with Google Mobile Services (GMS) via the C2DM registration intent to obtain FCM tokens, requiring only that GMS (Google Play Services) is present on the device.
To include this framework in your project, add the following
dependency to your Package.swift file:
let package = Package(
name: "my-package",
products: [
.library(name: "MyProduct", targets: ["MyTarget"]),
],
dependencies: [
.package(url: "https://source.skip.dev/skip-notify.git", "0.0.0"..<"2.0.0"),
],
targets: [
.target(name: "MyTarget", dependencies: [
.product(name: "SkipNotify", package: "skip-notify")
])
]
)import SkipNotify
do {
let token = try await SkipNotify.shared.fetchNotificationToken()
print("Push token: \(token)")
} catch {
print("Failed to get push token: \(error)")
}On iOS, this registers with APNs and returns the device token as a hex string. On Android, this sends a C2DM registration intent to GMS and returns the FCM registration token.
Before requesting a token on Android, you can check whether Google Mobile Services is available on the device:
if SkipNotify.shared.isGMSAvailable {
let token = try await SkipNotify.shared.fetchNotificationToken()
} else {
print("GMS not available: \(SkipNotify.shared.gmsStatusDescription)")
}| Property | iOS | Android (with GMS) | Android (without GMS) |
|---|---|---|---|
isGMSAvailable |
false |
true |
false |
gmsStatusDescription |
"GMS not applicable (iOS)" |
"GMS available" |
"GMS not available" |
If your Firebase project requires a specific sender ID (GCM project number), pass it when fetching the token:
let token = try await SkipNotify.shared.fetchNotificationToken(senderID: "123456789")Standard APNs flow using UIApplication.shared.registerForRemoteNotifications().
The token is received via NotificationCenter observers for
didRegisterForRemoteNotificationsWithDeviceToken and
didFailToRegisterForRemoteNotificationsWithError.
Instead of depending on com.google.firebase:firebase-messaging,
SkipNotify interfaces directly with Google Mobile Services via the
com.google.android.c2dm.intent.REGISTER intent:
- Checks GMS availability by resolving the C2DM registration service
- Sends a registration
Intenttocom.google.android.gmswith aMessengercallback - GMS responds asynchronously with a
Messagecontaining theregistration_id(FCM token)
This approach:
- Eliminates the
firebase-messagingtransitive dependency tree - Works on any device with Google Play Services installed
- Produces the same FCM token that
FirebaseMessaging.getInstance().tokenwould return - Does not require Firebase configuration files (
google-services.json) for token retrieval alone
Follow the steps described in the Registering your app with APNs documentation:
- Select your app from the App Store Connect Certificates, Identifiers & Profiles page and select "Capabilities" and turn on Push Notifications then click "Save"
- Use the Push Notifications Console to send a test message to your app.
No additional Gradle dependencies or google-services.json file is required
for token retrieval. GMS (Google Play Services) must be present on the device.
To receive push messages, your app will need to register a BroadcastReceiver
for the com.google.android.c2dm.intent.RECEIVE action in AndroidManifest.xml:
<receiver android:name=".PushMessageReceiver"
android:permission="com.google.android.c2dm.permission.SEND"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>This software is licensed under the Mozilla Public License 2.0.