Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jason-shen/e79a5464eccf6ff1a94e32da8bcdb25b to your computer and use it in GitHub Desktop.
Save jason-shen/e79a5464eccf6ff1a94e32da8bcdb25b to your computer and use it in GitHub Desktop.
Expo Modules Voip Push Token

Introduction

This gist shows the very basic bare minimum to get a voip push token in expo 53.

This is not really production ready as it is missing some reset logic and tests, but it is easily expandable.

Getting Started

  1. Navigate to your project root
  2. Run the following command: npx create-expo-module --local expo-voip-push-token
  3. Remove all of the View and Web based files, we will not be needing those.
  4. Replace the Relevant Files with the ones in the gist. Podfile, Gradle Files, and Manifests are not modified.
export interface VoipToken {
voipToken: string;
}
export type ExpoVoipPushTokenModuleEvents = {
onRegistration: (params: VoipToken) => void;
notification: (params: { payload: Record<string, any> }) => void;
};
package expo.modules.voippushtoken
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import java.net.URL
class ExpoVoipPushTokenModule : Module() {
override fun definition() = ModuleDefinition {
Name("ExpoVoipPushToken")
Events("onRegistration", "notification")
Function("registerVoipPushToken") {
// do nothing, as this is technically IOS only
}
}
}
import ExpoModulesCore
import Foundation
import PushKit
class VoipPushDelegate: NSObject, PKPushRegistryDelegate {
var onTokenReceived: ((String) -> Void)?
var onIncomingPush: ((PKPushPayload) -> Void)?
func pushRegistry(
_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType
) {
guard type == .voIP else { return }
let tokenData = pushCredentials.token
let tokenParts = tokenData.map { String(format: "%02x", $0) }
let token = tokenParts.joined()
onTokenReceived?(token)
}
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType,
completion: @escaping () -> Void
) {
guard type == .voIP else {
completion()
return
}
onIncomingPush?(payload)
completion()
}
}
public final class ExpoVoipPushTokenModule: Module {
private var voipRegistry: PKPushRegistry?
private let delegate = VoipPushDelegate()
private var currentVoipToken: String?
private func initializePushRegistry() {
let registry = PKPushRegistry(queue: .main)
registry.delegate = delegate
registry.desiredPushTypes = [.voIP]
self.voipRegistry = registry
delegate.onTokenReceived = { [weak self] token in
self?.currentVoipToken = token
self?.sendEvent("onRegistration", ["voipToken": token])
}
delegate.onIncomingPush = { [weak self] payload in
let payloadDict = payload.dictionaryPayload
self?.sendEvent("notification", ["payload": payloadDict])
}
}
public func definition() -> ModuleDefinition {
Name("ExpoVoipPushToken")
Events("onRegistration", "notification")
Function("registerVoipPushToken") {
initializePushRegistry()
}
}
}
import { NativeModule, requireNativeModule } from 'expo';
import { ExpoVoipPushTokenModuleEvents } from './ExpoVoipPushToken.types';
declare class ExpoVoipPushTokenModule extends NativeModule<ExpoVoipPushTokenModuleEvents> {
registerVoipPushToken(): void;
}
// This call loads the native module object from the JSI.
export default requireNativeModule<ExpoVoipPushTokenModule>('ExpoVoipPushToken');
// Reexport the native module. On web, it will be resolved to ExpoVoipPushTokenModule.web.ts
// and on native platforms to ExpoVoipPushTokenModule.ts
export { default } from './src/ExpoVoipPushTokenModule';
export * from './src/ExpoVoipPushToken.types';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment