Skip to content
This repository was archived by the owner on Jun 23, 2025. It is now read-only.

Commit 004565d

Browse files
authored
Merge pull request #81 from superwall/ir/add-web-delegate-methods
Ir/add web delegate methods
2 parents 066bded + 4a764cd commit 004565d

10 files changed

Lines changed: 396 additions & 2 deletions

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

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

5+
## 2.1.0 (Beta 1)
6+
7+
### Enhancements
8+
9+
- Adds `didRedeem` and `willRedeem` to support web checkout
10+
- Upgrades iOS SDK to 4.3.7 [View iOS SDK release notes](https://github.com/superwall/Superwall-iOS/releases/tag/4.3.7).
11+
12+
513
## 2.0.14
614

715
### Enhancements

example/src/MySuperwallDelegate.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
SuperwallEventInfo,
66
EventType,
77
} from '../../src';
8+
import type { RedemptionResult } from '../../src/public/RedemptionResults';
89

910
export class MySuperwallDelegate extends SuperwallDelegate {
1011
subscriptionStatusDidChange(
@@ -77,4 +78,12 @@ export class MySuperwallDelegate extends SuperwallDelegate {
7778
): void {
7879
console.log(`[${level}] ${scope}: ${message}`, info, error);
7980
}
81+
82+
willRedeemLink(): void {
83+
console.log('Will redeem link');
84+
}
85+
86+
didRedeemLink(result: RedemptionResult): void {
87+
console.log('Did redeem link:', result);
88+
}
8089
}

ios/Bridges/SuperwallDelegateBridge.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,12 @@ final class SuperwallDelegateBridge: SuperwallDelegate {
7979
private func sendEvent(withName name: String, body: [String: Any]) {
8080
SuperwallReactNative.emitter.sendEvent(withName: name, body: body)
8181
}
82+
83+
func willRedeemLink() {
84+
sendEvent(withName: "willRedeemLink", body: [:])
85+
}
86+
87+
func didRedeemLink(withResult result: RedemptionResult) {
88+
sendEvent(withName: "didRedeemLink", body: result.toJson())
89+
}
8290
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//
2+
// RedemptionResult+Json.swift
3+
// SuperwallKit
4+
//
5+
// Created on 14/03/2025.
6+
//
7+
8+
import SuperwallKit
9+
10+
extension RedemptionResult {
11+
func toJson() -> [String: Any] {
12+
var map: [String: Any] = [:]
13+
14+
switch self {
15+
case let .success(code, redemptionInfo):
16+
map["status"] = "SUCCESS"
17+
map["code"] = code
18+
map["redemptionInfo"] = redemptionInfo.toJson()
19+
case let .error(code, error):
20+
map["status"] = "ERROR"
21+
map["code"] = code
22+
map["error"] = error.toJson()
23+
case let .expiredCode(code, info):
24+
map["status"] = "CODE_EXPIRED"
25+
map["code"] = code
26+
map["expired"] = info.toJson()
27+
case .invalidCode(let code):
28+
map["status"] = "INVALID_CODE"
29+
map["code"] = code
30+
case let .expiredSubscription(code, redemptionInfo):
31+
map["status"] = "EXPIRED_SUBSCRIPTION"
32+
map["code"] = code
33+
map["redemptionInfo"] = redemptionInfo.toJson()
34+
}
35+
36+
return map
37+
}
38+
}
39+
40+
extension RedemptionResult.ErrorInfo {
41+
func toJson() -> [String: Any] {
42+
return ["message": self.message]
43+
}
44+
}
45+
46+
extension RedemptionResult.ExpiredCodeInfo {
47+
func toJson() -> [String: Any] {
48+
var map: [String: Any] = [:]
49+
50+
map["resent"] = self.resent
51+
if let obfuscatedEmail = self.obfuscatedEmail {
52+
map["obfuscatedEmail"] = obfuscatedEmail
53+
}
54+
55+
return map
56+
}
57+
}
58+
59+
extension RedemptionResult.RedemptionInfo {
60+
func toJson() -> [String: Any] {
61+
var map: [String: Any] = [:]
62+
63+
map["ownership"] = self.ownership.toJson()
64+
map["purchaserInfo"] = self.purchaserInfo.toJson()
65+
if let paywallInfo = self.paywallInfo {
66+
map["paywallInfo"] = paywallInfo.toJson()
67+
}
68+
map["entitlements"] = self.entitlements.map { $0.toJson() }
69+
70+
return map
71+
}
72+
}
73+
74+
extension RedemptionResult.RedemptionInfo.Ownership {
75+
func toJson() -> [String: Any] {
76+
var map: [String: Any] = [:]
77+
78+
switch self {
79+
case .appUser(let appUserId):
80+
map["type"] = "APP_USER"
81+
map["appUserId"] = appUserId
82+
case .device(let deviceId):
83+
map["type"] = "DEVICE"
84+
map["deviceId"] = deviceId
85+
}
86+
87+
return map
88+
}
89+
}
90+
91+
extension RedemptionResult.RedemptionInfo.PurchaserInfo {
92+
func toJson() -> [String: Any] {
93+
var map: [String: Any] = [:]
94+
95+
map["appUserId"] = self.appUserId
96+
if let email = self.email {
97+
map["email"] = email
98+
}
99+
map["storeIdentifiers"] = self.storeIdentifiers.toJson()
100+
101+
return map
102+
}
103+
}
104+
105+
extension RedemptionResult.RedemptionInfo.PurchaserInfo.StoreIdentifiers {
106+
func toJson() -> [String: Any] {
107+
var map: [String: Any] = [:]
108+
109+
switch self {
110+
case let .stripe(customerId, subscriptionIds):
111+
map["store"] = "STRIPE"
112+
map["stripeCustomerId"] = customerId
113+
map["stripeSubscriptionIds"] = subscriptionIds
114+
case let .unknown(store, additionalInfo):
115+
map["store"] = store
116+
// Add all the additional info to the map
117+
for (key, value) in additionalInfo {
118+
map[key] = value
119+
}
120+
}
121+
122+
return map
123+
}
124+
}
125+
126+
extension RedemptionResult.RedemptionInfo.PaywallInfo {
127+
func toJson() -> [String: Any] {
128+
var map: [String: Any] = [:]
129+
130+
map["identifier"] = self.identifier
131+
map["placementName"] = self.placementName
132+
map["placementParams"] = self.placementParams
133+
map["variantId"] = self.variantId
134+
map["experimentId"] = self.experimentId
135+
136+
return map
137+
}
138+
}

ios/SuperwallReactNative.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class SuperwallReactNative: RCTEventEmitter {
1717
"purchaseFromAppStore",
1818
"purchaseFromGooglePlay",
1919
"paywallWillOpenURL",
20+
"willRedeemLink",
21+
"didRedeemLink",
2022
"restore",
2123
"paywallPresentationHandler",
2224
"subscriptionStatusDidChange",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@superwall/react-native-superwall",
3-
"version": "2.0.14",
3+
"version": "2.1.0-beta.1",
44
"description": "The React Native package for Superwall",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

src/index.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { PresentationResult } from './public/PresentationResult';
1717
import { fromJson as paywallResultFromJson } from './public/PaywallResult';
1818
import { EntitlementsInfo } from './public/EntitlementsInfo';
1919
import type { LogLevel } from './public/LogLevel';
20+
import { RedemptionResults } from './public/RedemptionResults';
2021
const { version } = require('../package.json');
2122

2223
const LINKING_ERROR =
@@ -249,6 +250,15 @@ export default class Superwall {
249250
const url = new URL(data.url);
250251
Superwall.delegate?.paywallWillOpenURL(url);
251252
});
253+
254+
this.eventEmitter.addListener('willRedeemLink', async () => {
255+
Superwall.delegate?.willRedeemLink();
256+
});
257+
258+
this.eventEmitter.addListener('didRedeemLink', async (data) => {
259+
const result = RedemptionResults.fromJson(data.result);
260+
Superwall.delegate?.didRedeemLink(result);
261+
});
252262
}
253263

254264
private async observeSubscriptionStatus() {

0 commit comments

Comments
 (0)