Skip to content

Commit

Permalink
Create purchases_flutter_ui package (#919)
Browse files Browse the repository at this point in the history
Creates `purchases_flutter_ui` flutter package in a folder with the
functionality to `presentPaywall`/`presentPaywallIfNeeded` and removes
it from the main sdk `purchases_flutter`.

This allows to keep the min sdk version of the main sdk lower, while
still requiring a higher minSdk version for the new library.

The way to import the library now is to add in the pubspec.yaml:
```
dependencies:
   purchases_flutter: X.Y.Z
   purchases_flutter_ui: X.Y.Z
```
  • Loading branch information
tonidero authored Jan 4, 2024
1 parent 2d36abb commit ede6a5d
Show file tree
Hide file tree
Showing 40 changed files with 770 additions and 137 deletions.
45 changes: 44 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,14 @@ jobs:
project: revenuecat_examples/purchase_tester
- flutter-get-dependencies:
project: api_tester
- flutter-get-dependencies:
project: purchases_flutter_ui
- run:
name: Analyze code
command: flutter analyze
- run:
name: Analyze code for purchases_flutter_ui
command: cd purchases_flutter_ui && flutter analyze

test:
description: "Run tests for Flutter"
Expand All @@ -180,6 +185,9 @@ jobs:
- run:
name: Run tests
command: flutter test
- run:
name: Run tests for purchases_flutter_ui
command: cd purchases_flutter_ui && flutter test

api_test:
description: "Run API tests for Flutter"
Expand Down Expand Up @@ -316,6 +324,9 @@ jobs:
- run:
name: Dry Run Release
command: flutter pub publish --dry-run
- run:
name: Dry Run Release for purchases_flutter_ui
command: cd purchases_flutter_ui && flutter pub publish --dry-run

update-hybrid-common-versions:
description: "Creates a PR updating purchases-hybrid-common to latest release"
Expand All @@ -335,8 +346,9 @@ jobs:
version:<< pipeline.parameters.version >> \
open_pr:true \
automatic_release:<< pipeline.parameters.automatic >>
make-release:
description: "Publishes the new version to pub.dev and creates a github release"
description: "Publishes a new version of purchases-flutter to pub.dev and creates a github release"
docker:
- image: ghcr.io/cirruslabs/flutter:stable
steps:
Expand All @@ -348,6 +360,32 @@ jobs:
name: release
command: bundle exec fastlane release

make-release-purchases-flutter-ui:
description: "Publishes a new version of purchases-flutter-ui to pub.dev and creates a github release"
docker:
- image: ghcr.io/cirruslabs/flutter:stable
steps:
- checkout
- revenuecat/install-gem-unix-dependencies:
cache-version: v1
- revenuecat/trust-github-key
- run:
name: release
command: bundle exec fastlane release_purchases_flutter_ui

github_release:
description: "Creates a github release with the current version"
docker:
- image: cimg/ruby:3.1.2
steps:
- checkout
- revenuecat/install-gem-unix-dependencies:
cache-version: v1
- revenuecat/trust-github-key
- run:
name: release
command: bundle exec fastlane github_release_current_version

workflows:
danger:
jobs:
Expand Down Expand Up @@ -389,6 +427,11 @@ workflows:
- hold
<<: *release-branches
- make-release: *release-tags
- make-release-purchases-flutter-ui: *release-tags
- github_release:
requires:
- make-release
- make-release-purchases-flutter-ui
weekly-run-workflow:
when:
and:
Expand Down
26 changes: 26 additions & 0 deletions .pubignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
revenuecat_examples
scripts
migrations
fastlane
api_tester
codegen.sh
Dangerfile
Gemfile
Gemfile.lock
pubspec.lock

# Imported from .gitignore
vendor
.bundle
flutter
**/Podfile.lock
*.bck
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
**/android/key.properties
*.jks
2 changes: 0 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,4 @@ dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.revenuecat.purchases:purchases-hybrid-common:$common_version"
// TODO: Separate into different library
implementation "com.revenuecat.purchases:purchases-hybrid-common-ui:$common_version"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.revenuecat.purchases_flutter;

import static com.revenuecat.purchases.hybridcommon.ui.PaywallHelpersKt.presentPaywallFromFragment;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
Expand All @@ -25,8 +23,6 @@
import com.revenuecat.purchases.hybridcommon.SubscriberAttributesKt;
import com.revenuecat.purchases.hybridcommon.mappers.CustomerInfoMapperKt;
import com.revenuecat.purchases.models.InAppMessageType;
import com.revenuecat.purchases.ui.revenuecatui.ExperimentalPreviewRevenueCatUIPurchasesAPI;
import com.revenuecat.purchases.ui.revenuecatui.activity.PaywallResult;

import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -133,17 +129,6 @@ public Activity getActivity() {
return registrar != null ? registrar.activity() : activity;
}

private @Nullable FlutterFragmentActivity getActivityFragment() {
final Activity activity = getActivity();

if (activity instanceof FlutterFragmentActivity) {
return (FlutterFragmentActivity) activity;
} else {
Log.e(TAG, "Paywalls require your activity to subclass FlutterFragmentActivity");
return null;
}
}

@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
switch (call.method) {
Expand Down Expand Up @@ -370,13 +355,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
syncObserverModeAmazonPurchase(productID, receiptID, amazonUserID, isoCurrencyCode,
price, result);
break;
case "presentPaywall":
presentPaywall(result, null);
break;
case "presentPaywallIfNeeded":
final String requiredEntitlementIdentifier = call.argument("requiredEntitlementIdentifier");
presentPaywall(result, requiredEntitlementIdentifier);
break;
default:
result.notImplemented();
break;
Expand Down Expand Up @@ -745,24 +723,6 @@ private void showInAppMessages(final ArrayList<Integer> messageTypes, final Resu
result.success(null);
}

@OptIn(markerClass = ExperimentalPreviewRevenueCatUIPurchasesAPI.class)
private void presentPaywall(final Result result, final @Nullable String requiredEntitlementIdentifier) {
final FlutterFragmentActivity fragment = getActivityFragment();
if (fragment != null) {
presentPaywallFromFragment(
fragment,
requiredEntitlementIdentifier
);
result.success(null);
} else {
result.error(
String.valueOf(PurchasesErrorCode.UnknownError.getCode()),
"Make sure your MainActivity inherits from FlutterFragmentActivity",
null
);
}
}

private void runOnUiThread(Runnable runnable) {
handler.post(runnable);
}
Expand Down
5 changes: 0 additions & 5 deletions api_tester/lib/api_tests/purchases_flutter_api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,4 @@ class _PurchasesFlutterApiTest {
Future<void> future = Purchases.showInAppMessages(types: {InAppMessageType.billingIssue,
InAppMessageType.priceIncreaseConsent, InAppMessageType.generic});
}

void _checkPaywalls() async {
Future<void> future1 = Purchases.presentPaywall();
Future<void> future2 = Purchases.presentPaywallIfNeeded("test");
}
}
10 changes: 10 additions & 0 deletions api_tester/lib/api_tests/purchases_flutter_ui_api_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:purchases_flutter_ui/purchases_flutter_ui.dart';

// ignore_for_file: unused_element
// ignore_for_file: unused_local_variable
class _PurchasesFlutterApiTest {
void _checkPresentPaywall() async {
Future<void> future1 = RevenueCatUI.presentPaywall();
Future<void> future2 = RevenueCatUI.presentPaywallIfNeeded("test");
}
}
1 change: 1 addition & 0 deletions api_tester/lib/api_tests_import.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ import 'package:api_tester/api_tests/models/store_product_wrapper_api_test.dart'
import 'package:api_tester/api_tests/models/store_transaction_api_test.dart';
import 'package:api_tester/api_tests/models/subscription_option_wrapper_api_test.dart';
import 'package:api_tester/api_tests/purchases_flutter_api_test.dart';
import 'package:api_tester/api_tests/purchases_flutter_ui_api_test.dart';
2 changes: 2 additions & 0 deletions api_tester/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ dev_dependencies:

purchases_flutter:
path: ../
purchases_flutter_ui:
path: ../purchases_flutter_ui

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down
30 changes: 28 additions & 2 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ files_with_version_number = {
'./ios/Classes/PurchasesFlutterPlugin.m' => ['return @"{x}"'],
'./android/build.gradle' => ['version \'{x}\''],
'./android/src/main/java/com/revenuecat/purchases_flutter/PurchasesFlutterPlugin.java' => ['PLUGIN_VERSION = "{x}"'],
'./purchases_flutter_ui/pubspec.yaml' => ['version: {x}'],
'./purchases_flutter_ui/ios/purchases_flutter_ui.podspec' => ['s.version = \'{x}\''],
'./purchases_flutter_ui/macos/purchases_flutter_ui.podspec' => ['s.version = \'{x}\''],
'./purchases_flutter_ui/android/build.gradle' => ['version \'{x}\''],
}

repo_name = 'purchases-flutter'
Expand Down Expand Up @@ -85,16 +89,35 @@ end

desc "Create release"
lane :release do |options|
# Remove purchases_flutter_ui so it's not included in the release of the main SDK
# Can't use .pubignore because it causes files to not be found when trying to
# deploy purchases_flutter_ui
sh('rm', '-rf', 'purchases_flutter_ui')
Dir.chdir('..') do
sh('flutter', 'pub', 'publish', '--dry-run')
end
github_release(version: current_version_number)
setup_credentials_file
setup_credentials_file
Dir.chdir('..') do
sh('flutter', 'pub', 'publish', '--force')
end
end

desc "Create purchases_flutter_ui release"
lane :release_purchases_flutter_ui do |options|
Dir.chdir('../purchases_flutter_ui') do
sh('flutter', 'pub', 'publish', '--dry-run')
end
setup_credentials_file
Dir.chdir('../purchases_flutter_ui') do
sh('flutter', 'pub', 'publish', '--force')
end
end

desc "Make github release with current version number"
lane :github_release_current_version do |options|
github_release(version: current_version_number)
end

desc "Make github release"
lane :github_release do |options|
create_github_release(
Expand Down Expand Up @@ -141,6 +164,9 @@ lane :update_hybrid_common do |options|
'ios/purchases_flutter.podspec' => ['s.dependency \'PurchasesHybridCommon\', \'{x}\''],
'macos/purchases_flutter.podspec' => ['s.dependency \'PurchasesHybridCommon\', \'{x}\''],
'android/build.gradle' => ['ext.common_version = \'{x}\''],
'purchases_flutter_ui/ios/purchases_flutter_ui.podspec' => ['s.dependency \'PurchasesHybridCommon\', \'{x}\''],
'purchases_flutter_ui/macos/purchases_flutter_ui.podspec' => ['s.dependency \'PurchasesHybridCommon\', \'{x}\''],
'purchases_flutter_ui/android/build.gradle' => ['ext.common_version = \'{x}\''],
}

if dry_run
Expand Down
16 changes: 16 additions & 0 deletions fastlane/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ Automatically bumps version, edit changelog, and create pull request

Create release

### release_purchases_flutter_ui

```sh
[bundle exec] fastlane release_purchases_flutter_ui
```

Create purchases_flutter_ui release

### github_release_current_version

```sh
[bundle exec] fastlane github_release_current_version
```

Make github release with current version number

### github_release

```sh
Expand Down
44 changes: 0 additions & 44 deletions ios/Classes/PurchasesFlutterPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ @interface PurchasesFlutterPlugin () <RCPurchasesDelegate>
@property (nonatomic, retain) NSObject <FlutterPluginRegistrar> *registrar;
@property (nonatomic, retain) NSMutableArray<RCStartPurchaseBlock> *startPurchaseBlocks;

@property (nonatomic, strong) id paywallProxy;

@end

NSString *PurchasesCustomerInfoUpdatedEvent = @"Purchases-CustomerInfoUpdated";
Expand All @@ -33,16 +31,6 @@ - (instancetype)initWithChannel:(FlutterMethodChannel *)channel
self.channel = channel;
self.registrar = registrar;

#if TARGET_OS_IPHONE
if (@available(iOS 15.0, *)) {
self.paywallProxy = [PaywallProxy new];
} else {
self.paywallProxy = nil;
}
#else
self.paywallProxy = nil;
#endif

return self;
}

Expand Down Expand Up @@ -232,10 +220,6 @@ - (void)handleMethodCall:(FlutterMethodCall *)call
} else if ([@"syncObserverModeAmazonPurchase" isEqualToString:call.method]) {
// NOOP
result(nil);
} else if ([@"presentPaywall" isEqualToString:call.method]) {
[self presentPaywallWithResult:result requiredEntitlementIdentifier:nil];
} else if ([@"presentPaywallIfNeeded" isEqualToString:call.method]) {
[self presentPaywallWithResult:result requiredEntitlementIdentifier:arguments[@"requiredEntitlementIdentifier"]];
} else {
result(FlutterMethodNotImplemented);
}
Expand Down Expand Up @@ -612,34 +596,6 @@ - (void)setLogHandlerWithResult:(FlutterResult)result {
result(nil);
}

#pragma mark -
#pragma mark Paywalls

#if TARGET_OS_IPHONE
- (PaywallProxy *)paywalls API_AVAILABLE(ios(15.0)){
return self.paywallProxy;
}
#endif

- (void)presentPaywallWithResult:(FlutterResult)result requiredEntitlementIdentifier:(NSString * _Nullable)requiredEntitlementIdentifier {
#if TARGET_OS_IPHONE
if (@available(iOS 15.0, *)) {
if (requiredEntitlementIdentifier) {
[self.paywalls presentPaywallIfNeededWithRequiredEntitlementIdentifier:requiredEntitlementIdentifier];
} else {
[self.paywalls presentPaywall];
}
} else {
NSLog(@"[Purchases] Warning: tried to display paywall, but it's only available on iOS 15.0 or greater.");
}
#else
NSLog(@"[Purchases] Warning: tried to display paywall, but it's only available on iOS 15.0 or greater.");
#endif

result(nil);
}


#pragma mark -
#pragma mark Delegate Methods

Expand Down
Loading

0 comments on commit ede6a5d

Please sign in to comment.