Ich habe diesen Revenuecat Superwall -Controller von Superwall -Dokumenten zum Umgang mit Revenuecat -Einkäufen und -Theuchern und anderen Dingen in iOS und Android kopiert. In einem Projekt habe ich dies so verwendet. Kaufen Sie bei Google Play and Store PordURDUSE Ich weiß nicht, dass es alles gleich war, warum in einem anderen Projekt dieser Controller so viele Fehler hat und ich nicht weiß, wie ich diese Beacuse in früheren Projekten beheben kann.
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
import 'package:superwallkit_flutter/superwallkit_flutter.dart' hide LogLevel;
class RCPurchaseController extends PurchaseController {
// MARK: Configure and sync subscription Status
/// Makes sure that Superwall knows the customers subscription status by
/// changing `Superwall.shared.subscriptionStatus`
Future configureAndSyncSubscriptionStatus() async {
// Configure RevenueCat
await Purchases.setLogLevel(LogLevel.debug);
final configuration = Platform.isIOS
? PurchasesConfiguration('ios_rc_key')
: PurchasesConfiguration('android_rc_key');
await Purchases.configure(configuration);
// Listen for changes
Purchases.addCustomerInfoUpdateListener((customerInfo) async {
// Gets called whenever new CustomerInfo is available
final entitlements = customerInfo.entitlements.active.keys
.map((id) => Entitlement(id: id))
.toSet();
final hasActiveEntitlementOrSubscription = customerInfo
.hasActiveEntitlementOrSubscription(); // Why? -> https://www.revenuecat.com/docs/entitlements#entitlements
if (hasActiveEntitlementOrSubscription) {
await Superwall.shared.setSubscriptionStatus(
SubscriptionStatusActive(entitlements: entitlements));
} else {
await Superwall.shared
.setSubscriptionStatus(SubscriptionStatusInactive());
}
});
}
// MARK: Handle Purchases
/// Makes a purchase from App Store with RevenueCat and returns its
/// result. This gets called when someone tries to purchase a product on
/// one of your paywalls from iOS.
@override
Future purchaseFromAppStore(String productId) async {
// Find products matching productId from RevenueCat
final products = await PurchasesAdditions.getAllProducts([productId]);
// Get first product for product ID (this will properly throw if empty)
final storeProduct = products.firstOrNull;
if (storeProduct == null) {
return PurchaseResult.failed(
'Failed to find store product for $productId');
}
final purchaseResult = await _purchaseStoreProduct(storeProduct);
return purchaseResult;
}
/// Makes a purchase from Google Play with RevenueCat and returns its
/// result. This gets called when someone tries to purchase a product on
/// one of your paywalls from Android.
@override
Future purchaseFromGooglePlay(
String productId, String? basePlanId, String? offerId) async {
// Find products matching productId from RevenueCat
List products =
await PurchasesAdditions.getAllProducts([productId]);
// Choose the product which matches the given base plan.
// If no base plan set, select first product or fail.
String storeProductId = "$productId:$basePlanId";
// Try to find the first product where the googleProduct's basePlanId matches the given basePlanId.
StoreProduct? matchingProduct;
// Loop through each product in the products list.
for (final product in products) {
// Check if the current product's basePlanId matches the given basePlanId.
if (product.identifier == storeProductId) {
// If a match is found, assign this product to matchingProduct.
matchingProduct = product;
// Break the loop as we found our matching product.
break;
}
}
// If a matching product is not found, then try to get the first product from the list.
StoreProduct? storeProduct =
matchingProduct ?? (products.isNotEmpty ? products.first : null);
// If no product is found (either matching or the first one), return a failed purchase result.
if (storeProduct == null) {
return PurchaseResult.failed("Product not found");
}
switch (storeProduct.productCategory) {
case ProductCategory.subscription:
SubscriptionOption? subscriptionOption =
await _fetchGooglePlaySubscriptionOption(
storeProduct, basePlanId, offerId);
if (subscriptionOption == null) {
return PurchaseResult.failed(
"Valid subscription option not found for product.");
}
return await _purchaseSubscriptionOption(subscriptionOption);
case ProductCategory.nonSubscription:
return await _purchaseStoreProduct(storeProduct);
case null:
return PurchaseResult.failed("Unable to determine product category");
}
}
Future _fetchGooglePlaySubscriptionOption(
StoreProduct storeProduct,
String? basePlanId,
String? offerId,
) async {
final subscriptionOptions = storeProduct.subscriptionOptions;
if (subscriptionOptions != null && subscriptionOptions.isNotEmpty) {
// Concatenate base + offer ID
final subscriptionOptionId =
_buildSubscriptionOptionId(basePlanId, offerId);
// Find first subscription option that matches the subscription option ID or use the default offer
SubscriptionOption? subscriptionOption;
// Search for the subscription option with the matching ID
for (final option in subscriptionOptions) {
if (option.id == subscriptionOptionId) {
subscriptionOption = option;
break;
}
}
// If no matching subscription option is found, use the default option
subscriptionOption ??= storeProduct.defaultOption;
// Return the subscription option
return subscriptionOption;
}
return null;
}
Future _purchaseSubscriptionOption(
SubscriptionOption subscriptionOption) async {
// Define the async perform purchase function
Future performPurchase() async {
// Attempt to purchase product
CustomerInfo customerInfo =
await Purchases.purchaseSubscriptionOption(subscriptionOption);
return customerInfo;
}
PurchaseResult purchaseResult =
await _handleSharedPurchase(performPurchase);
return purchaseResult;
}
Future _purchaseStoreProduct(
StoreProduct storeProduct) async {
// Define the async perform purchase function
Future performPurchase() async {
// Attempt to purchase product
CustomerInfo customerInfo =
await Purchases.purchaseStoreProduct(storeProduct);
return customerInfo;
}
PurchaseResult purchaseResult =
await _handleSharedPurchase(performPurchase);
return purchaseResult;
}
// MARK: Shared purchase
Future _handleSharedPurchase(
Future Function() performPurchase) async {
try {
// Perform the purchase using the function provided
CustomerInfo customerInfo = await performPurchase();
print(customerInfo.activeSubscriptions.length);
print(customerInfo.entitlements.all.length);
print(customerInfo.entitlements.active);
// Handle the results
if (customerInfo.hasActiveEntitlementOrSubscription()) {
return PurchaseResult.purchased;
} else {
return PurchaseResult.failed("No active subscriptions found.");
}
} on PlatformException catch (e) {
var errorCode = PurchasesErrorHelper.getErrorCode(e);
if (errorCode == PurchasesErrorCode.paymentPendingError) {
return PurchaseResult.pending;
} else if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
return PurchaseResult.cancelled;
} else {
return PurchaseResult.failed(
e.message ?? "Purchase failed in RCPurchaseController");
}
}
}
// MARK: Handle Restores
/// Makes a restore with RevenueCat and returns `.restored`, unless an error is thrown.
/// This gets called when someone tries to restore purchases on one of your paywalls.
@override
Future restorePurchases() async {
try {
CustomerInfo customerInfo = await Purchases.restorePurchases();
await configureAndSyncSubscriptionStatus();
Superwall.shared.setUserAttributes({
'entitlements': customerInfo.entitlements.active.keys.join(','),
'isSubscribed': customerInfo.hasActiveEntitlementOrSubscription(),
});
return RestorationResult.restored;
} on PlatformException catch (e) {
// Error restoring purchases
return RestorationResult.failed(
e.message ?? "Restore failed in RCPurchaseController");
}
}
}
// MARK: Helpers
String _buildSubscriptionOptionId(String? basePlanId, String? offerId) {
String result = '';
if (basePlanId != null) {
result += basePlanId;
}
if (offerId != null) {
if (basePlanId != null) {
result += ':';
}
result += offerId;
}
return result;
}
extension CustomerInfoAdditions on CustomerInfo {
bool hasActiveEntitlementOrSubscription() {
return (activeSubscriptions.isNotEmpty || entitlements.active.isNotEmpty);
}
}
extension PurchasesAdditions on Purchases {
static Future getAllProducts(
List productIdentifiers) async {
final subscriptionProducts = await Purchases.getProducts(productIdentifiers,
productCategory: ProductCategory.subscription);
final nonSubscriptionProducts = await Purchases.getProducts(
productIdentifiers,
productCategory: ProductCategory.nonSubscription);
final combinedProducts = [
...subscriptionProducts,
...nonSubscriptionProducts
];
return combinedProducts;
}
}
< /code>
Konfiguration in main.dart < /p>
RCPurchaseController purchaseController = RCPurchaseController();
await purchaseController.configureAndSyncSubscriptionStatus();
SuperwallOptions options = SuperwallOptions();
options.logging.level = LogLevel.warn;
options.logging.scopes = {
LogScope.paywallPresentation,
LogScope.paywallEvents,
LogScope.transactions,
};
final apiKey = Platform.isAndroid
? ''
: '';
Superwall.configure(
apiKey,
purchaseController: purchaseController,
options: options,
);
final revenueApiKey = Platform.isAndroid
? ''
: '';
await Purchases.setDebugLogsEnabled(true);
await Purchases.configure(PurchasesConfiguration(revenueApiKey));
< /code>
Fehler
beim Kauf von Googleplay < /p>
Der Körper könnte normal abgeschlossen sein, was dazu führt, dass 'null' zurückgegeben wird, aber der Rückkehrtyp 'FutureOr' ist ein potenziell nicht nullbarer Typ. /> String ProductID,
String?The name 'StoreProduct' is defined in the libraries 'package:purchases_flutter/models/store_product_wrapper.dart (via package:purchases_flutter/purchases_flutter.dart)' and 'package:superwallkit_flutter/src/public/StoreProduct.dart (via package:superwallkit_flutter/superwallkit_flutter.dart)'.
Versuchen Sie, 'als Präfix' für eine der Importanweisungen zu verwenden oder den Namen bis auf einen der Imports zu verbergen.>
Ich habe diesen Revenuecat Superwall -Controller von Superwall -Dokumenten zum Umgang mit Revenuecat -Einkäufen und -Theuchern und anderen Dingen in iOS und Android kopiert. In einem Projekt habe ich dies so verwendet. Kaufen Sie bei Google Play and Store PordURDUSE Ich weiß nicht, dass es alles gleich war, warum in einem anderen Projekt dieser Controller so viele Fehler hat und ich nicht weiß, wie ich diese Beacuse in früheren Projekten [url=viewtopic.php?t=23756]beheben[/url] kann.[code]import 'dart:io';
class RCPurchaseController extends PurchaseController { // MARK: Configure and sync subscription Status /// Makes sure that Superwall knows the customers subscription status by /// changing `Superwall.shared.subscriptionStatus` Future configureAndSyncSubscriptionStatus() async { // Configure RevenueCat await Purchases.setLogLevel(LogLevel.debug); final configuration = Platform.isIOS ? PurchasesConfiguration('ios_rc_key') : PurchasesConfiguration('android_rc_key'); await Purchases.configure(configuration);
// Listen for changes Purchases.addCustomerInfoUpdateListener((customerInfo) async { // Gets called whenever new CustomerInfo is available final entitlements = customerInfo.entitlements.active.keys .map((id) => Entitlement(id: id)) .toSet();
final hasActiveEntitlementOrSubscription = customerInfo .hasActiveEntitlementOrSubscription(); // Why? -> https://www.revenuecat.com/docs/entitlements#entitlements
/// Makes a purchase from App Store with RevenueCat and returns its /// result. This gets called when someone tries to purchase a product on /// one of your paywalls from iOS. @override Future purchaseFromAppStore(String productId) async { // Find products matching productId from RevenueCat final products = await PurchasesAdditions.getAllProducts([productId]);
// Get first product for product ID (this will properly throw if empty) final storeProduct = products.firstOrNull;
if (storeProduct == null) { return PurchaseResult.failed( 'Failed to find store product for $productId'); }
final purchaseResult = await _purchaseStoreProduct(storeProduct); return purchaseResult; }
/// Makes a purchase from Google Play with RevenueCat and returns its /// result. This gets called when someone tries to purchase a product on /// one of your paywalls from Android. @override Future purchaseFromGooglePlay( String productId, String? basePlanId, String? offerId) async { // Find products matching productId from RevenueCat List products = await PurchasesAdditions.getAllProducts([productId]);
// Choose the product which matches the given base plan. // If no base plan set, select first product or fail. String storeProductId = "$productId:$basePlanId";
// Try to find the first product where the googleProduct's basePlanId matches the given basePlanId. StoreProduct? matchingProduct;
// Loop through each product in the products list. for (final product in products) { // Check if the current product's basePlanId matches the given basePlanId. if (product.identifier == storeProductId) { // If a match is found, assign this product to matchingProduct. matchingProduct = product; // Break the loop as we found our matching product. break; } }
// If a matching product is not found, then try to get the first product from the list. StoreProduct? storeProduct = matchingProduct ?? (products.isNotEmpty ? products.first : null);
// If no product is found (either matching or the first one), return a failed purchase result. if (storeProduct == null) { return PurchaseResult.failed("Product not found"); }
switch (storeProduct.productCategory) { case ProductCategory.subscription: SubscriptionOption? subscriptionOption = await _fetchGooglePlaySubscriptionOption( storeProduct, basePlanId, offerId); if (subscriptionOption == null) { return PurchaseResult.failed( "Valid subscription option not found for product."); } return await _purchaseSubscriptionOption(subscriptionOption); case ProductCategory.nonSubscription: return await _purchaseStoreProduct(storeProduct); case null: return PurchaseResult.failed("Unable to determine product category"); } }
if (subscriptionOptions != null && subscriptionOptions.isNotEmpty) { // Concatenate base + offer ID final subscriptionOptionId = _buildSubscriptionOptionId(basePlanId, offerId);
// Find first subscription option that matches the subscription option ID or use the default offer SubscriptionOption? subscriptionOption;
// Search for the subscription option with the matching ID for (final option in subscriptionOptions) { if (option.id == subscriptionOptionId) { subscriptionOption = option; break; } }
// If no matching subscription option is found, use the default option subscriptionOption ??= storeProduct.defaultOption;
// Return the subscription option return subscriptionOption; }
return null; }
Future _purchaseSubscriptionOption( SubscriptionOption subscriptionOption) async { // Define the async perform purchase function Future performPurchase() async { // Attempt to purchase product CustomerInfo customerInfo = await Purchases.purchaseSubscriptionOption(subscriptionOption); return customerInfo; }
// MARK: Shared purchase Future _handleSharedPurchase( Future Function() performPurchase) async { try { // Perform the purchase using the function provided CustomerInfo customerInfo = await performPurchase(); print(customerInfo.activeSubscriptions.length); print(customerInfo.entitlements.all.length); print(customerInfo.entitlements.active);
// Handle the results if (customerInfo.hasActiveEntitlementOrSubscription()) { return PurchaseResult.purchased; } else { return PurchaseResult.failed("No active subscriptions found."); } } on PlatformException catch (e) { var errorCode = PurchasesErrorHelper.getErrorCode(e); if (errorCode == PurchasesErrorCode.paymentPendingError) { return PurchaseResult.pending; } else if (errorCode == PurchasesErrorCode.purchaseCancelledError) { return PurchaseResult.cancelled; } else { return PurchaseResult.failed( e.message ?? "Purchase failed in RCPurchaseController"); } } }
// MARK: Handle Restores
/// Makes a restore with RevenueCat and returns `.restored`, unless an error is thrown. /// This gets called when someone tries to restore purchases on one of your paywalls. @override Future restorePurchases() async { try { CustomerInfo customerInfo = await Purchases.restorePurchases(); await configureAndSyncSubscriptionStatus();
< /code> Fehler beim Kauf von Googleplay < /p> Der Körper könnte normal abgeschlossen sein, was dazu führt, dass 'null' zurückgegeben wird, aber der Rückkehrtyp 'FutureOr' ist ein potenziell nicht nullbarer Typ. /> String ProductID, String?The name 'StoreProduct' is defined in the libraries 'package:purchases_flutter/models/store_product_wrapper.dart (via package:purchases_flutter/purchases_flutter.dart)' and 'package:superwallkit_flutter/src/public/StoreProduct.dart (via package:superwallkit_flutter/superwallkit_flutter.dart)'. [/code] Versuchen Sie, 'als Präfix' für eine der Importanweisungen zu verwenden oder den Namen bis auf einen der Imports zu verbergen.>
Ich bin neu mit Flutter. Ich möchte Sie nach diesem Fehler fragen.
Ich verwende Flutter mit Version
Flutter 3.16.9 • channel stable •
Framework • revision 41456452f2 (1 year, 2 months ago) •...
Ich habe versucht, die Menüschublade auf dem Hauptbildschirm zu implementieren, um Redundanz zu vermeiden. Wenn die Widget -Strukturen jedoch ein wenig komplex werden, kann das Menü mit dem...
Ich möchte eine Controller -Funktion mit Codesigniter aus einer anderen Controller -Funktion laden. Was ist der geeignete Weg, dies zu tun. Wenn Sie es also nennen, sollte auch geändert werden.
Schwerwiegender Fehler: Nicht erfasster Fehler: Klasse „App\Http\Controllers\Controller“ nicht gefunden in C:\Users\krithu\livechat\laravelapi\laravelbookstoreapi\bookstoreapi\bookstore\app\Http\...
Ich habe ein Widget mit Schwenkgeste in PageView und der PageView kann horizontal scrollen. Wenn ich das Widget horizontal schwenke, wird sich der PageView bewegen.
Was ich erwarte, ist dass die...