Skip to content

Commit 8e0a590

Browse files
mvanbeusekomfotiDim
authored andcommitted
[in_app_purchase] iOS example using in_app_purchase_ios package (flutter#3870)
Adds the example app for the in_app_purchase_ios platform implementation. All files that are part of the in_app_purcase_ios/example/ios folder have been copied over from in_app_purchase/example/ios. From all these files I only had to update the following: Renamed in_app_purchase_ios/ios/in_app_purchase.podspec file to in_app_purchase_ios/ios/in_app_purchase_ios.podspec (to match the new package name); Update the @import in_app_purchase statement to @import in_app_purchase_ios in the following files: InAppPurchasePluginTest.m PaymentQueueTest.m ProductRequestHandlerTest.m Stubs.h TranslatorTest.m I have tested the example project on my iPhone 12 Mini and it works fine. Also the iOS specific unit-test run correctly. Adds the iOS implementation for issue flutter/flutter#81695
1 parent 7a55d84 commit 8e0a590

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1861
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# In App Purchase iOS Example
2+
3+
Demonstrates how to use the In App Purchase iOS (IAP) Plugin.
4+
5+
## Getting Started
6+
7+
### Preparation
8+
9+
There's a significant amount of setup required for testing in app purchases
10+
successfully, including registering new app IDs and store entries to use for
11+
testing in App Store Connect. The App Store requires developers to configure
12+
an app with in-app items for purchase to call their in-app-purchase APIs.
13+
The App Store has extensive documentation on how to do this, and we've also
14+
included a high level guide below.
15+
16+
* [In-App Purchase (App Store)](https://developer.apple.com/in-app-purchase/)
17+
18+
### iOS
19+
20+
When using Xcode 12 and iOS 14 or higher you can run the example in the simulator or on a device without
21+
having to configure an App in App Store Connect. The example app is set up to use StoreKit Testing configured
22+
in the `example/ios/Runner/Configuration.storekit` file (as documented in the article [Setting Up StoreKit Testing in Xcode](https://developer.apple.com/documentation/xcode/setting_up_storekit_testing_in_xcode?language=objc)).
23+
To run the application take the following steps (note that it will only work when running from Xcode):
24+
25+
1. Open the example app with Xcode, `File > Open File` `example/ios/Runner.xcworkspace`;
26+
27+
2. Within Xcode edit the current scheme, `Product > Scheme > Edit Scheme...` (or press `Command + Shift + ,`);
28+
29+
3. Enable StoreKit testing:
30+
a. Select the `Run` action;
31+
b. Click `Options` in the action settings;
32+
c. Select the `Configuration.storekit` for the StoreKit Configuration option.
33+
34+
4. Click the `Close` button to close the scheme editor;
35+
36+
5. Select the device you want to run the example App on;
37+
38+
6. Run the application using `Product > Run` (or hit the run button).
39+
40+
When testing on pre-iOS 14 you can't run the example app on a simulator and you will need to configure an app in App Store Connect. You can do so by following the steps below:
41+
42+
1. Follow ["Workflow for configuring in-app
43+
purchases"](https://help.apple.com/app-store-connect/#/devb57be10e7), a
44+
detailed guide on all the steps needed to enable IAPs for an app. Complete
45+
steps 1 ("Sign a Paid Applications Agreement") and 2 ("Configure in-app
46+
purchases").
47+
48+
For step #2, "Configure in-app purchases in App Store Connect," you'll want
49+
to create the following products:
50+
51+
- A consumable with product ID `consumable`
52+
- An upgrade with product ID `upgrade`
53+
- An auto-renewing subscription with product ID `subscription_silver`
54+
- An non-renewing subscription with product ID `subscription_gold`
55+
56+
2. In XCode, `File > Open File` `example/ios/Runner.xcworkspace`. Update the
57+
Bundle ID to match the Bundle ID of the app created in step #1.
58+
59+
3. [Create a Sandbox tester
60+
account](https://help.apple.com/app-store-connect/#/dev8b997bee1) to test the
61+
in-app purchases with.
62+
63+
4. Use `flutter run` to install the app and test it. Note that you need to test
64+
it on a real device instead of a simulator. Next click on one of the products
65+
in the example App, this enables the "SANDBOX ACCOUNT" section in the iOS
66+
settings. You will now be asked to sign in with your sandbox test account to
67+
complete the purchase (no worries you won't be charged). If for some reason
68+
you aren't asked to sign-in or the wrong user is listed, go into the iOS
69+
settings ("Settings" -> "App Store" -> "SANDBOX ACCOUNT") and update your
70+
sandbox account from there. This procedure is explained in great detail in
71+
the [Testing In-App Purchases with Sandbox](https://developer.apple.com/documentation/storekit/in-app_purchase/testing_in-app_purchases_with_sandbox?language=objc) article.
72+
73+
74+
**Important:** signing into any production service (including iTunes!) with the
75+
sandbox test account will permanently invalidate it.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// @dart = 2.9
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:in_app_purchase_ios/in_app_purchase_ios.dart';
8+
import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart';
9+
import 'package:integration_test/integration_test.dart';
10+
11+
void main() {
12+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
13+
14+
testWidgets('Can create InAppPurchaseAndroid instance',
15+
(WidgetTester tester) async {
16+
InAppPurchaseIosPlatform.registerPlatform();
17+
final InAppPurchasePlatform androidPlatform =
18+
InAppPurchasePlatform.instance;
19+
expect(androidPlatform, isNotNull);
20+
});
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleDevelopmentRegion</key>
6+
<string>en</string>
7+
<key>CFBundleExecutable</key>
8+
<string>App</string>
9+
<key>CFBundleIdentifier</key>
10+
<string>io.flutter.flutter.app</string>
11+
<key>CFBundleInfoDictionaryVersion</key>
12+
<string>6.0</string>
13+
<key>CFBundleName</key>
14+
<string>App</string>
15+
<key>CFBundlePackageType</key>
16+
<string>FMWK</string>
17+
<key>CFBundleShortVersionString</key>
18+
<string>1.0</string>
19+
<key>CFBundleSignature</key>
20+
<string>????</string>
21+
<key>CFBundleVersion</key>
22+
<string>1.0</string>
23+
<key>MinimumOSVersion</key>
24+
<string>8.0</string>
25+
</dict>
26+
</plist>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2+
#include "Generated.xcconfig"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2+
#include "Generated.xcconfig"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Uncomment this line to define a global platform for your project
2+
# platform :ios, '9.0'
3+
4+
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5+
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6+
7+
project 'Runner', {
8+
'Debug' => :debug,
9+
'Profile' => :release,
10+
'Release' => :release,
11+
}
12+
13+
def flutter_root
14+
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15+
unless File.exist?(generated_xcode_build_settings_path)
16+
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17+
end
18+
19+
File.foreach(generated_xcode_build_settings_path) do |line|
20+
matches = line.match(/FLUTTER_ROOT\=(.*)/)
21+
return matches[1].strip if matches
22+
end
23+
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24+
end
25+
26+
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27+
28+
flutter_ios_podfile_setup
29+
30+
target 'Runner' do
31+
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
32+
33+
target 'in_app_purchase_pluginTests' do
34+
inherit! :search_paths
35+
36+
# Matches in_app_purchase test_spec dependency.
37+
pod 'OCMock','3.5'
38+
end
39+
end
40+
41+
post_install do |installer|
42+
installer.pods_project.targets.each do |target|
43+
flutter_additional_ios_build_settings(target)
44+
end
45+
end

0 commit comments

Comments
 (0)