react-native-purchases-ui 9.10.3 → 9.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,6 @@ Pod::Spec.new do |spec|
17
17
  spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
18
18
 
19
19
  spec.dependency "React-Core"
20
- spec.dependency "PurchasesHybridCommonUI", '17.41.0'
20
+ spec.dependency "PurchasesHybridCommonUI", '17.41.1'
21
21
  spec.swift_version = '5.7'
22
22
  end
@@ -59,7 +59,7 @@ android {
59
59
  minSdkVersion getExtOrIntegerDefault("minSdkVersion")
60
60
  targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
61
61
  versionCode 1
62
- versionName '9.10.3'
62
+ versionName '9.10.5'
63
63
  }
64
64
 
65
65
  buildTypes {
@@ -91,7 +91,7 @@ dependencies {
91
91
  //noinspection GradleDynamicVersion
92
92
  implementation "com.facebook.react:react-native:+"
93
93
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
94
- implementation 'com.revenuecat.purchases:purchases-hybrid-common-ui:17.41.0'
94
+ implementation 'com.revenuecat.purchases:purchases-hybrid-common-ui:17.41.1'
95
95
  implementation 'androidx.compose.ui:ui-android:1.5.4'
96
96
  implementation "androidx.appcompat:appcompat:1.6.1"
97
97
  }
@@ -23,6 +23,8 @@ API_AVAILABLE(ios(15.0))
23
23
 
24
24
  @property(strong, nonatomic) RCPaywallViewController *paywallViewController;
25
25
  @property(nonatomic) BOOL addedToHierarchy;
26
+ @property(nonatomic) BOOL didReceiveInitialOptions;
27
+ @property(strong, nonatomic) NSDictionary *pendingOptions;
26
28
 
27
29
  @end
28
30
 
@@ -31,7 +33,10 @@ API_AVAILABLE(ios(15.0))
31
33
  - (instancetype)initWithPaywallViewController:(RCPaywallViewController *)paywallViewController API_AVAILABLE(ios(15.0)) {
32
34
  NSParameterAssert(paywallViewController);
33
35
 
34
- if ((self = [super initWithFrame:paywallViewController.view.bounds])) {
36
+ // Don't access paywallViewController.view here - it triggers viewDidLoad which sets up
37
+ // the hostingController, making it impossible to set custom variables afterwards.
38
+ // See: https://github.com/RevenueCat/react-native-purchases/issues/1622
39
+ if ((self = [super initWithFrame:CGRectZero])) {
35
40
  _paywallViewController = paywallViewController;
36
41
  }
37
42
 
@@ -41,29 +46,32 @@ API_AVAILABLE(ios(15.0))
41
46
 
42
47
  - (void)reactSetFrame:(CGRect)frame
43
48
  {
44
- NSLog(@"RNPaywalls - reactSetFrame: %@", NSStringFromCGRect(frame));
45
-
46
49
  [super reactSetFrame: frame];
47
50
  }
48
51
 
49
52
  - (void)layoutSubviews {
50
53
  [super layoutSubviews];
51
54
 
52
- CGSize size = self.bounds.size;
53
- NSLog(@"RNPaywalls - Size on layoutSubviews: %@", NSStringFromCGSize(size));
54
-
55
55
  // Need to wait for this view to be in the hierarchy to look for the parent UIVC.
56
56
  // This is required to add a SwiftUI `UIHostingController` to the hierarchy in a way that allows
57
57
  // UIKit to read properties from the environment, like traits and safe area.
58
- if (!self.addedToHierarchy) {
58
+ //
59
+ // IMPORTANT: We also need to wait for setOptions: to be called (via didReceiveInitialOptions).
60
+ // Custom variables MUST be applied before accessing the PaywallViewController's view,
61
+ // because viewDidLoad sets up the hostingController which makes custom variables immutable.
62
+ // Note: options can be nil/empty (default usage), so we track the flag separately.
63
+ // See: https://github.com/RevenueCat/react-native-purchases/issues/1622
64
+ if (!self.addedToHierarchy && self.didReceiveInitialOptions) {
59
65
  UIViewController *parentController = self.parentViewController;
60
66
  if (parentController) {
67
+ // Apply custom variables BEFORE accessing .view (which triggers viewDidLoad).
68
+ [self applyCustomVariablesFromPendingOptions];
69
+
61
70
  self.paywallViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
62
71
  [parentController addChildViewController:self.paywallViewController];
63
72
  [self addSubview:self.paywallViewController.view];
64
73
  [self.paywallViewController didMoveToParentViewController:parentController];
65
74
 
66
- NSLog(@"RNPaywalls - Activating constraints");
67
75
  [NSLayoutConstraint activateConstraints:@[
68
76
  [self.paywallViewController.view.topAnchor constraintEqualToAnchor:self.topAnchor],
69
77
  [self.paywallViewController.view.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
@@ -72,13 +80,51 @@ API_AVAILABLE(ios(15.0))
72
80
  ]];
73
81
 
74
82
  self.addedToHierarchy = YES;
83
+
84
+ // Apply remaining options after adding to hierarchy
85
+ [self applyNonCustomVariableOptionsFromPendingOptions];
75
86
  }
76
87
  }
77
88
  }
78
89
 
79
90
  - (void)setOptions:(NSDictionary *)options {
80
91
  if (@available(iOS 15.0, *)) {
81
- NSDictionary *offering = options[@"offering"];
92
+ self.pendingOptions = options ?: @{};
93
+ self.didReceiveInitialOptions = YES;
94
+
95
+ if (self.addedToHierarchy) {
96
+ // View is already in hierarchy, apply non-custom-variable options only.
97
+ // Custom variables cannot be set after the PaywallViewController has loaded
98
+ // (the SDK will assert if we try). They must be set before viewDidLoad.
99
+ // See: https://github.com/RevenueCat/react-native-purchases/issues/1622
100
+ [self applyNonCustomVariableOptionsFromPendingOptions];
101
+ } else {
102
+ // View is not yet in hierarchy, trigger layout to apply options.
103
+ // Custom variables will be applied before adding to hierarchy in layoutSubviews.
104
+ [self setNeedsLayout];
105
+ }
106
+ } else {
107
+ NSLog(@"Error: attempted to present paywalls on unsupported iOS version.");
108
+ }
109
+ }
110
+
111
+ - (void)applyCustomVariablesFromPendingOptions {
112
+ if (@available(iOS 15.0, *)) {
113
+ NSDictionary *customVariables = self.pendingOptions[@"customVariables"];
114
+ if (customVariables && [customVariables isKindOfClass:[NSDictionary class]]) {
115
+ for (NSString *key in customVariables) {
116
+ NSString *value = customVariables[key];
117
+ if ([value isKindOfClass:[NSString class]]) {
118
+ [self.paywallViewController setCustomVariable:value forKey:key];
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ - (void)applyNonCustomVariableOptionsFromPendingOptions {
126
+ if (@available(iOS 15.0, *)) {
127
+ NSDictionary *offering = self.pendingOptions[@"offering"];
82
128
  if (offering && ![offering isKindOfClass:[NSNull class]]) {
83
129
  NSString *identifier = offering[@"identifier"];
84
130
  if (identifier) {
@@ -88,28 +134,16 @@ API_AVAILABLE(ios(15.0))
88
134
  }
89
135
  }
90
136
 
91
- NSString *fontFamily = options[@"fontFamily"];
137
+ NSString *fontFamily = self.pendingOptions[@"fontFamily"];
92
138
  if (fontFamily && [fontFamily isKindOfClass:[NSString class]] && fontFamily.length > 0) {
93
139
  [self.paywallViewController updateFontWithFontName:fontFamily];
94
140
  }
95
141
 
96
- NSNumber *displayCloseButtonValue = options[@"displayCloseButton"];
142
+ NSNumber *displayCloseButtonValue = self.pendingOptions[@"displayCloseButton"];
97
143
  BOOL displayCloseButton = [displayCloseButtonValue isKindOfClass:[NSNumber class]] ? [displayCloseButtonValue boolValue] : NO;
98
144
  if (displayCloseButton) {
99
145
  [self.paywallViewController updateWithDisplayCloseButton:displayCloseButton];
100
146
  }
101
-
102
- NSDictionary *customVariables = options[@"customVariables"];
103
- if (customVariables && [customVariables isKindOfClass:[NSDictionary class]]) {
104
- for (NSString *key in customVariables) {
105
- NSString *value = customVariables[key];
106
- if ([value isKindOfClass:[NSString class]]) {
107
- [self.paywallViewController setCustomVariable:value forKey:key];
108
- }
109
- }
110
- }
111
- } else {
112
- NSLog(@"Error: attempted to present paywalls on unsupported iOS version.");
113
147
  }
114
148
  }
115
149
 
@@ -204,7 +238,6 @@ didFailRestoringWithErrorDictionary:(NSDictionary *)errorDictionary API_AVAILABL
204
238
  }
205
239
 
206
240
  - (void)paywallViewController:(RCPaywallViewController *)controller didChangeSizeTo:(CGSize)size API_AVAILABLE(ios(15.0)) {
207
- NSLog(@"RNPaywalls - Paywall view wrapper did change size to: %@", NSStringFromCGSize(size));
208
241
  }
209
242
 
210
243
  - (void)paywallViewController:(RCPaywallViewController *)controller
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-purchases-ui",
3
3
  "title": "React Native Purchases UI",
4
- "version": "9.10.3",
4
+ "version": "9.10.5",
5
5
  "description": "React Native in-app purchases and subscriptions made easy. Supports iOS and Android.",
6
6
  "main": "lib/commonjs/index",
7
7
  "module": "lib/module/index",
@@ -78,7 +78,7 @@
78
78
  "peerDependencies": {
79
79
  "react": "*",
80
80
  "react-native": ">= 0.73.0",
81
- "react-native-purchases": "9.10.3",
81
+ "react-native-purchases": "9.10.5",
82
82
  "react-native-web": "*"
83
83
  },
84
84
  "peerDependenciesMeta": {
@@ -125,6 +125,6 @@
125
125
  ]
126
126
  },
127
127
  "dependencies": {
128
- "@revenuecat/purchases-typescript-internal": "17.41.0"
128
+ "@revenuecat/purchases-typescript-internal": "17.41.1"
129
129
  }
130
130
  }