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

RevenueCatUI initial support #852

Closed
wants to merge 20 commits into from
Closed

RevenueCatUI initial support #852

wants to merge 20 commits into from

Conversation

NachoSoto
Copy link
Contributor

@NachoSoto NachoSoto commented Nov 8, 2023

Depends on RevenueCat/purchases-hybrid-common#549

TODO:

  • Separate purchases-flutter-ui
  • Add methods to API tests
  • Add unit tests for methods

@NachoSoto NachoSoto requested a review from a team November 8, 2023 18:17
@NachoSoto NachoSoto force-pushed the paywalls branch 3 times, most recently from 36c8ea4 to 4328eaf Compare November 8, 2023 19:31
import io.flutter.app.FlutterActivity;
import io.flutter.view.FlutterMain;

public class EmbeddingV1Activity extends FlutterActivity {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was unused.

@NachoSoto NachoSoto force-pushed the paywalls branch 2 times, most recently from 9da4c22 to 598a3f8 Compare November 13, 2023 20:40
@NachoSoto NachoSoto changed the title [WIP] RevenueCatUI initial support RevenueCatUI initial support Nov 13, 2023
@NachoSoto NachoSoto marked this pull request as ready for review November 13, 2023 22:17
@NachoSoto NachoSoto mentioned this pull request Nov 13, 2023
tonidero and others added 2 commits November 23, 2023 10:54
Looks like `describeEnum` was deprecated in the latest Flutter version
and substituted with `name`. This PR changes current usages of that to
fix the linter.

From what I've been able to figure out, this `name` property is
available since Dart 2.15, which is our minimum version so we should be
good
Copy link
Member

@aboedo aboedo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking great so far, exciting times!

@kamaravichow
Copy link

This is great on iOS but on android as we turn our main activity into subclass, when user closes the paywall, the whole app closes off.

@tonidero
Copy link
Contributor

This is great on iOS but on android as we turn our main activity into subclass, when user closes the paywall, the whole app closes off.

Hi @kamaravichow, thanks for reporting! Could you open an issue in this repo and provide some more details? That behavior sounds like a crash. Is there a stack trace you can provide so we understand the issue?

@hamishjohnson
Copy link

hamishjohnson commented Dec 20, 2023

This is great on iOS but on android as we turn our main activity into subclass, when user closes the paywall, the whole app closes off.

Hi @kamaravichow, thanks for reporting! Could you open an issue in this repo and provide some more details? That behavior sounds like a crash. Is there a stack trace you can provide so we understand the issue?

I have the same issue:

From logs

E/AndroidRuntime( 2929): FATAL EXCEPTION: main
E/AndroidRuntime( 2929): Process: xx.xxx.xxxx, PID: 2929
E/AndroidRuntime( 2929): java.lang.IllegalStateException: Reply already submitted
E/AndroidRuntime( 2929): 	at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:435)
E/AndroidRuntime( 2929): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:272)
E/AndroidRuntime( 2929): 	at com.revenuecat.purchases_flutter.PurchasesFlutterActivity.onActivityResult(PurchasesFlutterActivity.java:51)
E/AndroidRuntime( 2929): 	at com.revenuecat.purchases_flutter.PurchasesFlutterActivity.onActivityResult(PurchasesFlutterActivity.java:22)
E/AndroidRuntime( 2929): 	at androidx.activity.result.ActivityResultRegistry$1.onStateChanged(ActivityResultRegistry.java:149)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.kt:251)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.kt:287)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.kt:136)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.kt:119)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.ReportFragment$Companion.dispatch$lifecycle_runtime_release(ReportFragment.kt:192)
E/AndroidRuntime( 2929): 	at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostStarted(ReportFragment.kt:121)
E/AndroidRuntime( 2929): 	at android.app.Activity.dispatchActivityPostStarted(Activity.java:1396)
E/AndroidRuntime( 2929): 	at android.app.Activity.performStart(Activity.java:8268)
E/AndroidRuntime( 2929): 	at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3853)
E/AndroidRuntime( 2929): 	at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
E/AndroidRuntime( 2929): 	at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
E/AndroidRuntime( 2929): 	at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
E/AndroidRuntime( 2929): 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
E/AndroidRuntime( 2929): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2317)
E/AndroidRuntime( 2929): 	at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 2929): 	at android.os.Looper.loop(Looper.java:246)
E/AndroidRuntime( 2929): 	at android.app.ActivityThread.main(ActivityThread.java:8625)
E/AndroidRuntime( 2929): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 2929): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
E/AndroidRuntime( 2929): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
I/Process ( 2929): Sending signal. PID: 2929 SIG: 9
Lost connection to device.

Exited.

@NachoSoto
Copy link
Contributor Author

@hamishjohnson that's the same as #902. We're currently looking into it, we'll have a fix on the next beta 🙏🏻

We forgot a `break` when calling this method, which caused it to fall to
the `default` case, resulting in the result being called twice, causing
a crash. This deals with #902
After RevenueCat/purchases-hybrid-common#602, we
can now use the `PaywallHelpers.presentPaywallFromFragment` method to
present the paywall and receive a result back using an internal view
model.

This makes it so the `PurchasesFlutterActivity` isn't needed anymore and
we can make use of that functionality, shared with other hybrids.

Note that this does mean developers need to make sure their android
activity inherits from `FlutterFragmentActivity` (or other
`FragmentActivity`) and not `FlutterActivity`, as we need to present the
fragment.

### TODO
- [x] Hide action bar:
RevenueCat/purchases-android#1532
- [x] Update PHC with those 2 changes.
This merges latest `main` into `paywalls`

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@tonidero tonidero mentioned this pull request Dec 22, 2023
### New Features
* 📱 Initial support for cross-platform RevenueCat Paywalls 🐾 🧱 (#852)

#### Instructions:
- For Android, you need to change your `MainActivity` to subclass
`FlutterFragmentActivity` instead of `FlutterActivity`.
- Update `purchases-flutter` in your `pubspec.yaml`:
```yaml
dependencies:
  purchases_flutter: 6.6.0-beta.3
```

#### Usage:
```dart
await Purchases.presentPaywallIfNeeded("pro");
```

#### Limitations:

- Currently only full screen paywalls are supported
- There is no way to detect paywall events other than using
`addCustomerInfoUpdateListener`
- Android's `minSdkVersion` is temporarily increased from `19` to `24`
to support paywalls. This will be reverted in a future release as we
split `purchases_flutter` and `purchases_flutter_ui`

### Breaking changes from previous beta

- `PurchasesFlutterActivity` has been removed. Use
`FlutterFragmentActivity` provided by Flutter instead

### Fixes from previous beta
* Fix `presentPaywallIfNeeded` (#904) via Toni Rico (@tonidero)

### Other Changes
* Update paywalls latest main (#906) via Toni Rico (@tonidero)
* Update to use PHC PaywallHelpers instead of custom activity (#903) via
Toni Rico (@tonidero)
* Fix flutter analyze deprecation warnings (#872)
@hamishjohnson
Copy link

I get this error:

Unhandled Exception: type 'Null' is not a subtype of type 'FutureOr<bool>'
#0      Purchases.presentPaywallIfNeeded (package:purchases_flutter/purchases_flutter.dart:944:7)
<asynchronous suspension>
#1      RevenuecatPurchaseRepository.showPaywallAndCheckStatus (package:radio_check/src/features/purchases/repositories/revenuecat_purchase_repository.dart:36:5)
<asynchronous suspension>
#2      useAsyncFuture.call (package:radio_check/src/helpers/riverpod/async_future.dart:42:22)
<asynchronous suspension>

This was in last beta version too.

Keep up the good work!

@renatogp
Copy link

I get this error:

Unhandled Exception: type 'Null' is not a subtype of type 'FutureOr<bool>'
#0      Purchases.presentPaywallIfNeeded (package:purchases_flutter/purchases_flutter.dart:944:7)
<asynchronous suspension>
#1      RevenuecatPurchaseRepository.showPaywallAndCheckStatus (package:radio_check/src/features/purchases/repositories/revenuecat_purchase_repository.dart:36:5)
<asynchronous suspension>
#2      useAsyncFuture.call (package:radio_check/src/helpers/riverpod/async_future.dart:42:22)
<asynchronous suspension>

This was in last beta version too.

Keep up the good work!

I'm also getting this error when calling Purchases.presentPaywall or Purchases.presentPaywallIfNeeded on iOS simulator and on the device (could try Android yet). The exception is raised as soon as the modal is displayed, not after closing or finishing the payment flow.

@tonidero
Copy link
Contributor

tonidero commented Jan 2, 2024

Hi @hamishjohnson and @renatogp. We're tracking that issue in #886. We are planning a fix for that issue soon which will remove some functionality. We will add it back with a better API in future releases.

tonidero and others added 6 commits January 2, 2024 19:05
Updates PHC to `8.10.0-beta.8`
Currently the `presentPaywall` and `presentPaywallIfNeeded` methods
return a boolean indicating whether a purchase happened in the paywall.
This API is confusing and not extensible and it wasn't properly working
in iOS, see: #886. This first PR removes the return value from the
method. In a future PR we will add proper result handling for the
paywalls. Until then, the clients won't know what happened when the
paywall was presented and will need to rely on the
`Purchases.getCustomerInfo()` method to respond appropriately.

This is a breaking change from the previous beta.
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
```
This renames the `purchases_flutter_ui` package added in #919 to
`purchases_ui_flutter`
Updates `paywalls` to the latest `main`

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This fixes some issues found in the pub score for the new package
`purchases-ui-flutter`
@tonidero tonidero mentioned this pull request Jan 5, 2024
### New features
* 📱 Initial support for cross-platform RevenueCat Paywalls 🐾 🧱 (#852)

#### Instructions:
- For Android, you need to change your `MainActivity` to subclass
`FlutterFragmentActivity` instead of `FlutterActivity`. Also, the min
sdk version of the new package is `24`. Please make sure your app's
`android/build.gradle` minSdkVersion has that or a higher version.
- Add `purchases-ui-flutter` in your `pubspec.yaml`:
```yaml
dependencies:
  purchases_ui_flutter: 6.15.0-beta.4
```

#### Usage:
```dart
import 'package:purchases_ui_flutter/purchases_ui_flutter.dart';

await RevenueCatUI.presentPaywallIfNeeded("pro");
```

#### Limitations:
- Currently only full screen paywalls are supported
- There is no way to detect paywall events other than using
`addCustomerInfoUpdateListener`

#### Breaking changes from previous beta:
- Paywalls functionality has been extracted into a new dependency called
purchases_ui_flutter. Add purchases_ui_flutter to your pubspec.yaml.
Before this release, it was part of the main RevenueCat SDK
`purchases_flutter`.
- A new import is required to use this functionality: `import
'package:purchases_ui_flutter/purchases_ui_flutter.dart';`
- Usage has changed the class from `Purchases.presentPaywall` to
`RevenueCatUI.presentPaywall`.
- `presentPaywall` and `presentPaywallIfNeeded` now don't return a
result. To detect purchases, please use `Purchases.getCustomerInfo` from
the `purchases_flutter` SDK. A return value will be added in future
releases.

### Other Changes
* Fix pub score for `purchases-ui-flutter` (#924) via Toni Rico
(@tonidero)
* Update `paywalls` to latest `main` (#923) via Toni Rico (@tonidero)
* Rename `purchases_flutter_ui` to `purchases_ui_flutter` (#921) via
Toni Rico (@tonidero)
* Separate paywalls into a different package (#919) via Toni Rico
(@tonidero)
* Remove result from presentPaywall methods (#916) via Toni Rico
(@tonidero)
* Update to use PHC PaywallHelpers instead of custom activity (#903) via
Toni Rico (@tonidero)
After splitting the ci jobs for deploying both the flutter and paywalls
sdks, we separated the github release to its own job to be executed
after those 2. However, it didn't execute in the last release. This
should fix that.
Adds a `PaywallResult` enum and makes it the return value of the
`presentPaywall` and `presentPaywallIfNeeded` methods
applicationId "com.revenuecat.api_tester"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion
// TODO: change
// minSdkVersion flutter.minSdkVersion
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonidero we should be able to change this now, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm we would need to split the API tests since currently they also have the new package. Not sure if it's worth doing that though?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh okay makes sense 👍🏻 I'll remove this then.

NachoSoto added a commit that referenced this pull request Jan 12, 2024
Squashed and rebased #852.
@NachoSoto
Copy link
Contributor Author

Merged with #931

@NachoSoto NachoSoto closed this Jan 12, 2024
@NachoSoto NachoSoto deleted the paywalls branch January 12, 2024 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants