Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.4.1 #26

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

The changelog for `Superwall`. Also see the [releases](https://github.com/superwall/react-native-superwall/releases) on GitHub.

## 1.4.1

### Enhancements

- Exposes `getPresentationResult(forEvent:params:)`. This returns a `PresentationResult`, which preemptively gets the result of registering an event. This helps you determine whether a particular event will present a paywall in the future.

## 1.4.0

### Enhancements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.superwall.sdk.misc.ActivityProvider
import com.superwall.sdk.misc.sdkVersion
import com.superwall.sdk.paywall.presentation.PaywallPresentationHandler
import com.superwall.sdk.paywall.presentation.dismiss
import com.superwall.sdk.paywall.presentation.get_presentation_result.getPresentationResult
import com.superwall.sdk.paywall.presentation.register
import com.superwallreactnative.bridges.SuperwallDelegateBridge
import com.superwallreactnative.models.IdentityOptions
Expand All @@ -28,6 +29,7 @@ import com.superwallreactnative.models.SuperwallOptions
import com.superwallreactnative.models.convertMapToReadableMap
import com.superwallreactnative.models.convertReadableMapToMap
import com.superwallreactnative.models.asString
import com.superwallreactnative.models.convertReadableMapToCompactMap
import com.superwallreactnative.models.toJson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -263,6 +265,21 @@ class SuperwallReactNativeModule(private val reactContext: ReactApplicationConte
}
}

@ReactMethod
fun getPresentationResult(
event: String,
params: ReadableMap?,
promise: Promise
) {
CoroutineScope(Dispatchers.IO).launch {
val paramsMap = params?.let { convertReadableMapToCompactMap(it) }
val result = Superwall.instance.getPresentationResult(event, paramsMap)
launch(Dispatchers.Main) {
promise.resolve(result.toJson())
}
}
}

@ReactMethod
fun preloadPaywalls(eventNames: ReadableArray) {
val eventNames = eventNames.toArrayList().toSet() as Set<String>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.superwallreactnative.models

import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReadableMap

import com.superwall.sdk.paywall.presentation.result.PresentationResult

fun PresentationResult.toJson(): ReadableMap {
val map = Arguments.createMap()

when (this) {
is PresentationResult.Holdout -> {
map.putString("type", "Holdout")
map.putMap("experiment", Experiment.toJson(experiment))
}

is PresentationResult.Paywall -> {
map.putString("type", "Paywall")
map.putMap("experiment", Experiment.toJson(experiment))
}

is PresentationResult.NoRuleMatch -> {
map.putString("type", "NoRuleMatch")
}

is PresentationResult.EventNotFound -> {
map.putString("type", "EventNotFound")
}

is PresentationResult.UserIsSubscribed -> {
map.putString("type", "UserIsSubscribed")
}

is PresentationResult.PaywallNotAvailable -> {
map.putString("type", "PaywallNotAvailable")
}
}

return map
}
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,20 @@ fun convertReadableMapToMap(readableMap: ReadableMap): Map<String, Any?> {
}
return map
}

fun convertReadableMapToCompactMap(readableMap: ReadableMap): Map<String, Any> {
val map: MutableMap<String, Any> = HashMap()
val iterator = readableMap.keySetIterator()
while (iterator.hasNextKey()) {
val key = iterator.nextKey()
when (val value = readableMap.getType(key)) {
ReadableType.String -> map[key] = readableMap.getString(key) ?: continue
ReadableType.Boolean -> map[key] = readableMap.getBoolean(key)
ReadableType.Number -> map[key] = readableMap.getDouble(key)
ReadableType.Map -> map[key] = convertReadableMapToMap(readableMap.getMap(key)!!)
ReadableType.Null -> continue
else -> {}
}
}
return map
}
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ PODS:
- React-Core
- SocketRocket (0.6.1)
- Superscript (0.1.12)
- superwall-react-native (1.4.0):
- superwall-react-native (1.4.1):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
Expand Down Expand Up @@ -1393,7 +1393,7 @@ SPEC CHECKSUMS:
RNPurchases: 06957eb2f35bd7bb336d32fccf3534d45a3fda8a
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Superscript: 1ed1b4364f93bd16be05d085bba7357dbab95c83
superwall-react-native: 43ee3985e7bf123b5ad71e361e32d50e93d5da4d
superwall-react-native: 6c5401f69c3185053bff9f09bfc52a2b97313eab
SuperwallKit: ff739c94ebc351ae210c8b0f0b3931e930d74053
Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312

Expand Down
27 changes: 27 additions & 0 deletions ios/Json/PresentationResult+Json.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation
import SuperwallKit

extension PresentationResult {
func toJson() -> [String: Any] {
switch self {
case .holdout(let experiment):
return [
"type": "Holdout",
"experiment": experiment.toJson(),
]
case .paywall(let experiment):
return [
"type": "Paywall",
"experiment": experiment.toJson(),
]
case .noRuleMatch:
return ["type": "NoRuleMatch"]
case .eventNotFound:
return ["type": "EventNotFound"]
case .userIsSubscribed:
return ["type": "UserIsSubscribed"]
case .paywallNotAvailable:
return ["type": "PaywallNotAvailable"]
}
}
}
7 changes: 7 additions & 0 deletions ios/SuperwallReactNative.mm
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ @interface RCT_EXTERN_MODULE(SuperwallReactNative, NSObject)
withRejecter:(RCTPromiseRejectBlock)reject
)

RCT_EXTERN_METHOD(
getPresentationResult:(NSString *)event
params:(NSDictionary *)options
withResolver:(RCTPromiseResolveBlock)resolve
withRejecter:(RCTPromiseRejectBlock)reject
)

RCT_EXTERN_METHOD(preloadAllPaywalls)

RCT_EXTERN_METHOD(preloadPaywalls:(NSArray<NSString *> *)eventNames)
Expand Down
12 changes: 12 additions & 0 deletions ios/SuperwallReactNative.swift
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,18 @@ class SuperwallReactNative: RCTEventEmitter {
}
}

@objc(getPresentationResult:params:withResolver:withRejecter:)
func getPresentationResult(
event: String,
params: [String: Any],
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock
) {
Superwall.shared.getPresentationResult(forEvent: event, params: params) { result in
resolve(result.toJson())
}
}

@objc(preloadPaywalls:)
func preloadPaywalls(forEvents eventNames: [String]) {
Superwall.shared.preloadPaywalls(forEvents: Set(eventNames))
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superwall/react-native-superwall",
"version": "1.4.0",
"version": "1.4.1",
"description": "The React Native package for Superwall",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
9 changes: 9 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { IdentityOptions } from './public/IdentityOptions';
import { EventEmitter } from 'events';
import { ConfigurationStatus } from './public/ConfigurationStatus';
import { ConfirmedAssignment } from './public/ConfirmedAssigments';
import type { PresentationResult } from './public/PresentationResult';
const { version } = require('../package.json');

const LINKING_ERROR =
Expand Down Expand Up @@ -330,6 +331,14 @@ export default class Superwall {
);
}

async getPresentationResult(
event: String,
params?: Map<String, any>
): Promise<PresentationResult> {
await this.awaitConfig();
return await SuperwallReactNative.getPresentationResult(event, params);
}

async getConfigurationStatus(): Promise<ConfigurationStatus> {
const configurationStatusString =
await SuperwallReactNative.getConfigurationStatus();
Expand Down
56 changes: 56 additions & 0 deletions src/public/PresentationResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Experiment } from './Experiment';

export abstract class PresentationResult {
static fromJson(json: any): PresentationResult {
let experiment: Experiment | undefined;
if (json.experiment) {
experiment = Experiment.fromJson(json.experiment);
}

switch (json.type) {
case 'Holdout':
if (!experiment) throw new Error('Holdout requires an experiment');
return new PresentationResultHoldout(experiment);
case 'Paywall':
if (!experiment) throw new Error('Paywall requires an experiment');
return new PresentationResultPaywall(experiment);
case 'NoRuleMatch':
return new PresentationResultNoRuleMatch();
case 'EventNotFound':
return new PresentationResultEventNotFound();
case 'UserIsSubscribed':
return new PresentationResultUserIsSubscribed();
case 'PaywallNotAvailable':
return new PresentationResultPaywallNotAvailable();
default:
throw new Error('Unknown PresentationResult type');
}
}
}

// Derived classes
export class PresentationResultEventNotFound extends PresentationResult {}

export class PresentationResultNoRuleMatch extends PresentationResult {}

export class PresentationResultUserIsSubscribed extends PresentationResult {}

export class PresentationResultPaywallNotAvailable extends PresentationResult {}

export class PresentationResultHoldout extends PresentationResult {
experiment: Experiment;

constructor(experiment: Experiment) {
super();
this.experiment = experiment;
}
}

export class PresentationResultPaywall extends PresentationResult {
experiment: Experiment;

constructor(experiment: Experiment) {
super();
this.experiment = experiment;
}
}
Loading