Setting the file. One moment.
Subchapter 9.1
references/native-module.mdMarkdown2 KBView on GitHub
Create a local Expo module so JS can detect when the app is running inside an App Clip and present the install prompt for the full app.
import ExpoModulesCore
import StoreKit
internal class MissingCurrentWindowSceneException: Exception {
override var reason: String {
"Cannot determine the current window scene in which to present the modal for requesting a review."
}
}
internal class MissingContainerURLException: Exception {
override var reason: String {
"Cannot determine the container URL."
}
}
public class AppClipModule: Module {
private static let isAppClip: Bool = {
if let infoPlist = Bundle.main.infoDictionary, let _ = infoPlist["NSAppClip"] as? [String: Any] {
return true
}
return false
}()
public func definition() -> ModuleDefinition {
Name("AppClip")
Constant("isAppClip") {
AppClipModule.isAppClip
}
// Display overlay to advertise full app.
// https://developer.apple.com/documentation/app_clips/recommending_your_app_to_app_clip_users
AsyncFunction("prompt") {
if #available(iOS 16, *) {
guard let currentScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
throw MissingCurrentWindowSceneException()
}
let config = SKOverlay.AppClipConfiguration(position: .bottom)
let overlay = SKOverlay(configuration: config)
overlay.present(in: currentScene)
}
}.runOnQueue(DispatchQueue.main)
}
}import { NativeModule, requireOptionalNativeModule } from "expo";
declare class AppClipModule extends NativeModule<{}> {
prompt(): void;
isAppClip?: boolean;
}
const AppClipNative = requireOptionalNativeModule<AppClipModule>("AppClip");
if (AppClipNative?.isAppClip) {
navigator.appClip = {
prompt: AppClipNative.prompt,
};
}
declare global {
interface Navigator {
/**
* Only available in an App Clip context.
* @expo
*/
appClip?: {
/** Open the SKOverlay */
prompt: () => void;
};
}
}
export {};if (navigator.appClip) { ... }navigator.appClip?.prompt()