diff --git a/README.md b/README.md index 8b35605..4090d0e 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,14 @@ ## Integration ### Requirements -* iOS 9 or later. -* Android 4.4 or later. + +- iOS 9 or later. +- Android 4.4 or later. ### Supported Products - :white_check_mark: Klarna Post Purchase Experience -- :x: Klarna Payments +- :white_check_mark: Klarna Payments - :x: Klarna Checkout #### Post Purchase Experience @@ -29,6 +30,7 @@ As of now, credentials needed for Post Purchase Experience is only available through Klarna Delivery Managers. If you want to test this integration, please contact your Delivery Manager to get required information regarding Post Purchase Experience. ### Klarna In-App SDK Documentation + [Overview of the SDK](https://developers.klarna.com/documentation/in-app/) ### Flutter Dependency @@ -44,17 +46,20 @@ Add `flutter_klarna_inapp_sdk` as a dependency in your `pubspec.yaml` file accor Initializes a KlarnaHybridSDK instance which will also be used for Post Purchase operations. ###### Parameters -| Name | Type | Description | -| ---- | ---- | ----------- | -| returnUrl | `String` | An app-defined URL scheme the component uses to return customers to your app. | + +| Name | Type | Description | +| --------- | -------- | ----------------------------------------------------------------------------- | +| returnUrl | `String` | An app-defined URL scheme the component uses to return customers to your app. | ##### registerEventListener() + Registers a listener, receiving merchant events from Klarna web components. ###### Parameters -| Name | Type | Description | -| ---- | ---- | ----------- | -| listener | `Function(String)` | A listener function receiving the event body string as a parameter. | + +| Name | Type | Description | +| -------- | ------------------ | ------------------------------------------------------------------- | +| listener | `Function(String)` | A listener function receiving the event body string as a parameter. | #### KlarnaPostPurchaseExperience @@ -63,12 +68,13 @@ Registers a listener, receiving merchant events from Klarna web components. Initializes new `WebView` and javascript Klarna Post Purchase Experience library. ###### Parameters -| Name | Type | Description | -| ---- | ---- | ----------- | -| locale | `String` | A string representing the user locale. For example: `se-SE` | -| purchaseCountry | `String` | A string representing the purchase country. For example: `SE` | -| design | `named optional` `String?` | A string representing the design ID. | -| environment | `named optional` `KlarnaPostPurchaseEnvironment?` | Region or playground environment for Post Purchase SDK. | + +| Name | Type | Description | +| --------------- | ------------------------------------------------- | ------------------------------------------------------------- | +| locale | `String` | A string representing the user locale. For example: `se-SE` | +| purchaseCountry | `String` | A string representing the purchase country. For example: `SE` | +| design | `named optional` `String?` | A string representing the design ID. | +| environment | `named optional` `KlarnaPostPurchaseEnvironment?` | Region or playground environment for Post Purchase SDK. | ##### destroy() @@ -79,32 +85,34 @@ Destroys any object, including `WebView` attached to the client. Load the Klarna widget for the operation. ###### Parameters -| Name | Type | Description | -| ---- | ---- | ----------- | -| locale | `named optional` `String?` | A string representing the user locale. | -| operationToken | `String` | The operation token for the related order returned from the post purchase api. | + +| Name | Type | Description | +| -------------- | -------------------------- | ------------------------------------------------------------------------------ | +| locale | `named optional` `String?` | A string representing the user locale. | +| operationToken | `String` | The operation token for the related order returned from the post purchase api. | ##### authorizationRequest() Called to kick off the oauth flow. ###### Parameters -| Name | Type | Description | -| ---- | ---- | ----------- | -| locale | `named optional` `String?` | A string representing the user locale. | -| clientId | `String` | The client_id for your application. | -| scope | `String` | A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values define the consent screen that Klarna displays to the user. | -| redirectUri | `String` | The “location” where the OAuth server redirects the user after the user completes the authorization flow. The value must exactly match one of the redirect_url values provided to Klarna in advance. | -| state | `named optional` `String?` | A string value that your application uses to maintain state between your authorization request and the authorization server's response. The Authorization server returns the exact value that you send to the redirect_url as a URL parameter. | -| loginHint | `named optional` `String?` | If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Klarna’s Authorization Server. The server uses the hint to simplify the login flow by prefilling the email field in the sign-in form. It’s recommended to use this as it will improve the customer experience. | -| responseType | `named optional` `String?` | The desired grant type. The value MUST be one of "code" for requesting an authorization code or "token" for requesting an access token (implicit grant). The default is "code" | +| Name | Type | Description | +| ------------ | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| locale | `named optional` `String?` | A string representing the user locale. | +| clientId | `String` | The client_id for your application. | +| scope | `String` | A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values define the consent screen that Klarna displays to the user. | +| redirectUri | `String` | The “location” where the OAuth server redirects the user after the user completes the authorization flow. The value must exactly match one of the redirect_url values provided to Klarna in advance. | +| state | `named optional` `String?` | A string value that your application uses to maintain state between your authorization request and the authorization server's response. The Authorization server returns the exact value that you send to the redirect_url as a URL parameter. | +| loginHint | `named optional` `String?` | If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Klarna’s Authorization Server. The server uses the hint to simplify the login flow by prefilling the email field in the sign-in form. It’s recommended to use this as it will improve the customer experience. | +| responseType | `named optional` `String?` | The desired grant type. The value MUST be one of "code" for requesting an authorization code or "token" for requesting an access token (implicit grant). The default is "code" | ## Development ### Getting Started After cloning the repository run the command below to setup the project. + ```shell script flutter packages get ``` @@ -123,59 +131,63 @@ Plugin implementation will be located at `flutter_klarna_inapp_sdk/java/com.klar Plugin implementation will be located at `Pods/Development Pods/flutter_klarna_inapp_sdk/../../example/ios/.symlinks/plugins/flutter_klarna_inapp_sdk/ios/Classes`. - ## Support -If you are having any issues using the SDK in your project or if you think that something is wrong with the SDK itself, please create an issue on [Github](https://github.com/klarna/flutter-klarna-inapp-sdk/issues) or report a bug by following the guidelines in the next section. +If you are having any issues using the SDK in your project or if you think that something is wrong with the SDK itself, please create an issue on [Github](https://github.com/klarna/flutter-klarna-inapp-sdk/issues) or report a bug by following the guidelines in the next section. ### How can I contribute? Thank you for reading this and taking the time to contribute to Klarna In-App SDK! Below is a set of guidelines to help you contribute whether you want to report a bug, come with suggestions or modify code. #### Reporting Bugs + This section will guide you through submitting a bug report for Klarna In-App SDK. -Before submitting a bug report, please check that the issue hasn't been reported before. If you find a *Closed* issue that seems to describe an issue that is similar to what you want to report, open a new issue and link to the original issue in the new one. When you have checked that the issue hasn't been reported before, please **fill out [the required template](https://github.com/klarna/flutter-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)** which will help us resolve the issue faster. +Before submitting a bug report, please check that the issue hasn't been reported before. If you find a _Closed_ issue that seems to describe an issue that is similar to what you want to report, open a new issue and link to the original issue in the new one. When you have checked that the issue hasn't been reported before, please **fill out [the required template](https://github.com/klarna/flutter-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)** which will help us resolve the issue faster. ##### Submitting a Bug Report + Submitted bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). To report a bug, create an issue and use [the template](https://github.com/klarna/flutter-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/bug_report.md) to provide information about the bug. Explain the problem thoroughly and include any additional information that you think might help the maintainers reproduce the issue. When creating the GitHub issue please make sure that you: -* **Use a clear and descriptive title** for the issue. -* **Describe the exact steps which reproduce the problem** with as many details as possible. It's generally better to provide too much than too little information. -* **Describe the behavior you observed after following the steps** and explain precisely what the problem is with that behavior. -* **Explain which behavior you expected instead** and why. -* **Provide screenshots and/or screen recordings** that might help explain the issue you are facing. To screen record a phone connected to Android Studio or an emulator, follow the steps [here](https://developer.android.com/studio/debug/am-video). To screen record on iOS, follow the steps described [here](https://support.apple.com/en-us/HT207935). -* **Include relevant logs in the bug report** by putting it in a [code block](https://help.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github#multiple-lines), a [file attachment](https://help.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) or in a [gist](https://help.github.com/en/github/writing-on-github/creating-gists) and provide a link to that gist. -* **Tell how recently you started having the issue.** When was the first time you experienced the issue and was it after updating the SDK version? Or has it always been a problem? -* If the problem started happening recently, **can you reproduce it in an older version of the SDK?** What's the most recent version in which the problem doesn't happen? -* **Can you reliably reproduce the issue?** If not, explain how often it occurs and under what conditions it usually happens. For example, in what environment you are running. +- **Use a clear and descriptive title** for the issue. +- **Describe the exact steps which reproduce the problem** with as many details as possible. It's generally better to provide too much than too little information. +- **Describe the behavior you observed after following the steps** and explain precisely what the problem is with that behavior. +- **Explain which behavior you expected instead** and why. +- **Provide screenshots and/or screen recordings** that might help explain the issue you are facing. To screen record a phone connected to Android Studio or an emulator, follow the steps [here](https://developer.android.com/studio/debug/am-video). To screen record on iOS, follow the steps described [here](https://support.apple.com/en-us/HT207935). +- **Include relevant logs in the bug report** by putting it in a [code block](https://help.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github#multiple-lines), a [file attachment](https://help.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) or in a [gist](https://help.github.com/en/github/writing-on-github/creating-gists) and provide a link to that gist. +- **Tell how recently you started having the issue.** When was the first time you experienced the issue and was it after updating the SDK version? Or has it always been a problem? +- If the problem started happening recently, **can you reproduce it in an older version of the SDK?** What's the most recent version in which the problem doesn't happen? +- **Can you reliably reproduce the issue?** If not, explain how often it occurs and under what conditions it usually happens. For example, in what environment you are running. Include details about the device/emulator/simulator you are experiencing the issue on: -* **Which version of the SDK are you using?** -* **Which OS is this a problem in, iOS, Android or both?** What version(s)? Also, add the appropriate label to the issue. -* **Did you experience the issue in simulator/emulator or on real device(s)?** +- **Which version of the SDK are you using?** +- **Which OS is this a problem in, iOS, Android or both?** What version(s)? Also, add the appropriate label to the issue. +- **Did you experience the issue in simulator/emulator or on real device(s)?** ## Contribution Before contributing, please read through the [Klarna In-App SDK documentation](https://developers.klarna.com/documentation/in-app/). ##### Branching + Prefix the branch you are going to work on depending on what you are working on (bug fix or feature). Use the following prefixes when creating a new branch: -* **feature/** if the branch contains a new feature, for example: `feature/my-shiny-feature`. -* **bugfix/** if the branch contains a bug fix, for example: `bugfix/my-bug-fix`. +- **feature/** if the branch contains a new feature, for example: `feature/my-shiny-feature`. +- **bugfix/** if the branch contains a bug fix, for example: `bugfix/my-bug-fix`. ##### Pull Requests + When creating a PR, please include as much information as possible about the type of enhancement, whether if it's a bugfix, new functionality, or any other change. There's [a template](https://github.com/klarna/flutter-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/pull-request.md) for you to fill out, which will make the review process for the maintainers faster. When creating a PR do it against the `master` branch. The PR should include: -* **A clear and descriptive title**. -* **Description of the issue** if you are fixing a bug together with a link to the relevant issue or **background for introducing a new feature**. +- **A clear and descriptive title**. +- **Description of the issue** if you are fixing a bug together with a link to the relevant issue or **background for introducing a new feature**. + [ci-image]: https://img.shields.io/badge/build-passing-brightgreen?style=flat-square [ci-url]: https://github.com/klarna/TODO [license-image]: https://img.shields.io/badge/license-Apache%202-blue?style=flat-square [license-url]: http://www.apache.org/licenses/LICENSE-2.0 [klarna-image]: https://img.shields.io/badge/%20-Developed%20at%20Klarna-black?labelColor=ffb3c7&style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAALQAAAAAQAAAtAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABCgAwAEAAAAAQAAAA4AAAAA0LMKiwAAAAlwSFlzAABuugAAbroB1t6xFwAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAAAVBJREFUKBVtkz0vREEUhsdXgo5qJXohkUgQ0fgFNFpR2V5ClP6CQu9PiB6lEL1I7B9A4/treZ47c252s97k2ffMmZkz5869m1JKL/AFbzAHaiRbmsIf4BdaMAZqMFsOXNxXkroKbxCPV5l8yHOJLVipn9/vEreLa7FguSN3S2ynA/ATeQuI8tTY6OOY34DQaQnq9mPCDtxoBwuRxPfAvPMWnARlB12KAi6eLTPruOOP4gcl33O6+Sjgc83DJkRH+h2MgorLzaPy68W48BG2S+xYnmAa1L+nOxEduMH3fgjGFvZeVkANZau68B6CrgJxWosFFpF7iG+h5wKZqwt42qIJtARu/ix+gqsosEq8D35o6R3c7OL4lAnTDljEe9B3Qa2BYzmHemDCt6Diwo6JY7E+A82OnN9HuoBruAQvUQ1nSxP4GVzBDRyBfygf6RW2/gD3NmEv+K/DZgAAAABJRU5ErkJggg== -[klarna-url]: https://github.com/klarna \ No newline at end of file +[klarna-url]: https://github.com/klarna diff --git a/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/FlutterKlarnaInappSdk.kt b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/FlutterKlarnaInappSdk.kt index 9ca6148..2e7a128 100644 --- a/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/FlutterKlarnaInappSdk.kt +++ b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/FlutterKlarnaInappSdk.kt @@ -1,6 +1,8 @@ package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk import androidx.annotation.NonNull +import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment.KlarnaPaymentViewWidgetFactory +import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment.KlarnaPaymentViewPlugin import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding @@ -20,6 +22,10 @@ public class FlutterKlarnaInappSdk : FlutterPlugin, ActivityAware { val eventChannel = EventChannel(flutterPluginBinding.flutterEngine.dartExecutor, it.key) eventChannel.setStreamHandler(it.value) } + + flutterPluginBinding + .platformViewRegistry + .registerViewFactory("plugins/klarna_payment_view", KlarnaPaymentViewWidgetFactory(flutterPluginBinding.binaryMessenger)) } // This static function is optional and equivalent to onAttachedToEngine. It supports the old @@ -46,6 +52,8 @@ public class FlutterKlarnaInappSdk : FlutterPlugin, ActivityAware { PluginContext.activity = registrar.activity() PluginContext.context = registrar.context() + + KlarnaPaymentViewPlugin.registerWith(registrar) } } diff --git a/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewPlugin.kt b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewPlugin.kt new file mode 100644 index 0000000..7bb179b --- /dev/null +++ b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewPlugin.kt @@ -0,0 +1,12 @@ +package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment + +import io.flutter.plugin.common.PluginRegistry + +object KlarnaPaymentViewPlugin { + fun registerWith(registrar: PluginRegistry.Registrar) { + registrar + .platformViewRegistry() + .registerViewFactory( + "plugins/klarna_payment_view", KlarnaPaymentViewWidgetFactory(registrar.messenger())) + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewWidget.kt b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewWidget.kt new file mode 100644 index 0000000..4c36d48 --- /dev/null +++ b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewWidget.kt @@ -0,0 +1,84 @@ +package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment + +import android.content.Context +import android.view.View +import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.PluginContext +import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.core.util.requireArgument +import com.klarna.mobile.sdk.api.payments.KlarnaPaymentCategory +import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView +import io.flutter.Log +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.platform.PlatformView + +class KlarnaPaymentViewWidget internal constructor(context: Context, id: Int, messenger: BinaryMessenger, creationParams: Map?) : PlatformView, MethodCallHandler { + private val methodChannel: MethodChannel + + private val paymentView: KlarnaPaymentView + + private val paymentCategories = mapOf( + "pay_now" to KlarnaPaymentCategory.PAY_NOW, + "pay_later" to KlarnaPaymentCategory.PAY_LATER, + "pay_over_time" to KlarnaPaymentCategory.SLICE_IT + ) + + override fun getView(): View { + return paymentView + } + + init { + val paymentCategory = creationParams!!["category"] as String + + methodChannel = MethodChannel(messenger, "plugins/klarna_payment_view_$id") + methodChannel.setMethodCallHandler(this) + paymentView = KlarnaPaymentView(PluginContext.context!!, paymentCategories[paymentCategory]!!, KlarnaPaymentSDKCallback(methodChannel)) + } + + override fun onMethodCall(methodCall: MethodCall, result: Result) { + when (methodCall.method) { + "initialize" -> initialize(methodCall, result) + "load" -> load(methodCall, result) + "authorize" -> authorize(methodCall, result) + "finalize" -> finalize(methodCall, result) + "reauthorize" -> reauthorize(methodCall, result) + "loadPaymentReview" -> loadPaymentReview(methodCall, result) + else -> result.notImplemented() + } + } + + private fun initialize(methodCall: MethodCall, result: Result) { + paymentView.initialize(methodCall.requireArgument("clientToken"), methodCall.requireArgument("returnUrl")) + result.success(null) + } + + private fun load(methodCall: MethodCall, result: Result) { + paymentView.load(methodCall.argument("args")) + result.success(null) + } + + private fun authorize(methodCall: MethodCall, result: Result) { + paymentView.authorize(methodCall.requireArgument("autoFinalize"), methodCall.argument("sessionData")) + result.success(null) + } + + private fun finalize(methodCall: MethodCall, result: Result) { + paymentView.finalize(methodCall.argument("sessionData")); + result.success(null) + } + + private fun reauthorize(methodCall: MethodCall, result: Result) { + paymentView.reauthorize(methodCall.argument("sessionData")); + result.success(null) + } + + private fun loadPaymentReview(methodCall: MethodCall, result: Result) { + paymentView.loadPaymentReview(); + result.success(null) + } + + override fun dispose() { + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewWidgetFactory.kt b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewWidgetFactory.kt new file mode 100644 index 0000000..71a4e6b --- /dev/null +++ b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/KlarnaPaymentViewWidgetFactory.kt @@ -0,0 +1,14 @@ +package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment + +import android.content.Context +import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment.KlarnaPaymentViewWidget +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.StandardMessageCodec +import io.flutter.plugin.platform.PlatformView +import io.flutter.plugin.platform.PlatformViewFactory + +class KlarnaPaymentViewWidgetFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) { + override fun create(context: Context, id: Int, args: Any?): PlatformView { + return KlarnaPaymentViewWidget(context = context, id = id, messenger = messenger, creationParams = args as Map?) + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/PaymentSDKCallback.kt b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/PaymentSDKCallback.kt new file mode 100644 index 0000000..5d342e9 --- /dev/null +++ b/android/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk/payment/PaymentSDKCallback.kt @@ -0,0 +1,49 @@ +package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment + +import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView +import com.klarna.mobile.sdk.api.payments.KlarnaPaymentViewCallback +import com.klarna.mobile.sdk.api.payments.KlarnaPaymentsSDKError +import io.flutter.plugin.common.MethodChannel + +internal class KlarnaPaymentSDKCallback constructor(methodChannel: MethodChannel) : KlarnaPaymentViewCallback { + private val callbackMethodChannel = methodChannel; + + override fun onAuthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?, finalizedRequired: Boolean?) { + val args = mapOf("authToken" to authToken, "approved" to approved, "finalizedRequired" to finalizedRequired) + callbackMethodChannel.invokeMethod("onAuthorized", args) + } + + override fun onErrorOccurred(view: KlarnaPaymentView, error: KlarnaPaymentsSDKError) { + val args = mapOf( + "message" to error.message, + "action" to error.action, + "name" to error.name, + "invalidFields" to error.invalidFields, + "isFatal" to error.isFatal + ) + callbackMethodChannel.invokeMethod("onErrorOccurred", args) + } + + override fun onFinalized(view: KlarnaPaymentView, approved: Boolean, authToken: String?) { + val args = mapOf("approved" to approved, "authToken" to authToken) + callbackMethodChannel.invokeMethod("onFinalized", args) + } + + override fun onInitialized(view: KlarnaPaymentView) { + callbackMethodChannel.invokeMethod("onInitialized", null) + } + + override fun onLoadPaymentReview(view: KlarnaPaymentView, showForm: Boolean) { + val args = mapOf("showForm" to showForm) + callbackMethodChannel.invokeMethod("onLoadPaymentReview", args) + } + + override fun onLoaded(view: KlarnaPaymentView) { + callbackMethodChannel.invokeMethod("onLoaded", null) + } + + override fun onReauthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?) { + val args = mapOf("approved" to approved, "authToken" to authToken) + callbackMethodChannel.invokeMethod("onReauthorized", args) + } +} \ No newline at end of file diff --git a/example/.gitignore b/examples/payments/.gitignore similarity index 100% rename from example/.gitignore rename to examples/payments/.gitignore diff --git a/example/.metadata b/examples/payments/.metadata similarity index 100% rename from example/.metadata rename to examples/payments/.metadata diff --git a/example/README.md b/examples/payments/README.md similarity index 100% rename from example/README.md rename to examples/payments/README.md diff --git a/example/android/.gitignore b/examples/payments/android/.gitignore similarity index 100% rename from example/android/.gitignore rename to examples/payments/android/.gitignore diff --git a/examples/payments/android/app/build.gradle b/examples/payments/android/app/build.gradle new file mode 100644 index 0000000..4d277c3 --- /dev/null +++ b/examples/payments/android/app/build.gradle @@ -0,0 +1,68 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.klarna.inapp.sdk.flutter_klarna_inapp_sdk_example" + minSdkVersion 19 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/examples/payments/android/app/src/debug/AndroidManifest.xml similarity index 100% rename from example/android/app/src/debug/AndroidManifest.xml rename to examples/payments/android/app/src/debug/AndroidManifest.xml diff --git a/example/android/app/src/main/AndroidManifest.xml b/examples/payments/android/app/src/main/AndroidManifest.xml similarity index 100% rename from example/android/app/src/main/AndroidManifest.xml rename to examples/payments/android/app/src/main/AndroidManifest.xml diff --git a/example/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt b/examples/payments/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt similarity index 100% rename from example/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt rename to examples/payments/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/examples/payments/android/app/src/main/res/drawable/launch_background.xml similarity index 100% rename from example/android/app/src/main/res/drawable/launch_background.xml rename to examples/payments/android/app/src/main/res/drawable/launch_background.xml diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/payments/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to examples/payments/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/payments/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to examples/payments/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/payments/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to examples/payments/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/payments/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to examples/payments/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/payments/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to examples/payments/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/values/styles.xml b/examples/payments/android/app/src/main/res/values/styles.xml similarity index 100% rename from example/android/app/src/main/res/values/styles.xml rename to examples/payments/android/app/src/main/res/values/styles.xml diff --git a/example/android/app/src/profile/AndroidManifest.xml b/examples/payments/android/app/src/profile/AndroidManifest.xml similarity index 100% rename from example/android/app/src/profile/AndroidManifest.xml rename to examples/payments/android/app/src/profile/AndroidManifest.xml diff --git a/example/android/build.gradle b/examples/payments/android/build.gradle similarity index 100% rename from example/android/build.gradle rename to examples/payments/android/build.gradle diff --git a/example/android/gradle.properties b/examples/payments/android/gradle.properties similarity index 100% rename from example/android/gradle.properties rename to examples/payments/android/gradle.properties diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/examples/payments/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from example/android/gradle/wrapper/gradle-wrapper.properties rename to examples/payments/android/gradle/wrapper/gradle-wrapper.properties diff --git a/example/android/settings.gradle b/examples/payments/android/settings.gradle similarity index 100% rename from example/android/settings.gradle rename to examples/payments/android/settings.gradle diff --git a/examples/payments/android/settings_aar.gradle b/examples/payments/android/settings_aar.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/examples/payments/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/example/ios/.gitignore b/examples/payments/ios/.gitignore similarity index 100% rename from example/ios/.gitignore rename to examples/payments/ios/.gitignore diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/examples/payments/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from example/ios/Flutter/AppFrameworkInfo.plist rename to examples/payments/ios/Flutter/AppFrameworkInfo.plist diff --git a/example/ios/Flutter/Debug.xcconfig b/examples/payments/ios/Flutter/Debug.xcconfig similarity index 100% rename from example/ios/Flutter/Debug.xcconfig rename to examples/payments/ios/Flutter/Debug.xcconfig diff --git a/example/ios/Flutter/Release.xcconfig b/examples/payments/ios/Flutter/Release.xcconfig similarity index 100% rename from example/ios/Flutter/Release.xcconfig rename to examples/payments/ios/Flutter/Release.xcconfig diff --git a/example/ios/Podfile b/examples/payments/ios/Podfile similarity index 100% rename from example/ios/Podfile rename to examples/payments/ios/Podfile diff --git a/examples/payments/ios/Podfile.lock b/examples/payments/ios/Podfile.lock new file mode 100644 index 0000000..e781636 --- /dev/null +++ b/examples/payments/ios/Podfile.lock @@ -0,0 +1,31 @@ +PODS: + - Flutter (1.0.0) + - flutter_klarna_inapp_sdk (0.0.1): + - Flutter + - KlarnaMobileSDK (~> 2.0.20) + - KlarnaMobileSDK (2.0.20): + - KlarnaMobileSDK/xcode-11.5-fat-basic (= 2.0.20) + - KlarnaMobileSDK/xcode-11.5-fat-basic (2.0.20) + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_klarna_inapp_sdk (from `.symlinks/plugins/flutter_klarna_inapp_sdk/ios`) + +SPEC REPOS: + trunk: + - KlarnaMobileSDK + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_klarna_inapp_sdk: + :path: ".symlinks/plugins/flutter_klarna_inapp_sdk/ios" + +SPEC CHECKSUMS: + Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_klarna_inapp_sdk: 751b9f9afbf3d6cd7f9afb6fe50b469d88c25ffe + KlarnaMobileSDK: 2f72b76a0650fe047fba0fd65e6782b5bacf1053 + +PODFILE CHECKSUM: 0ba44ad07df4ab62269dc769727cf0f12b1e453d + +COCOAPODS: 1.10.1 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/examples/payments/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from example/ios/Runner.xcodeproj/project.pbxproj rename to examples/payments/ios/Runner.xcodeproj/project.pbxproj diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/payments/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to examples/payments/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/payments/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to examples/payments/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/examples/payments/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to examples/payments/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/payments/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to examples/payments/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/example/ios/Runner/AppDelegate.swift b/examples/payments/ios/Runner/AppDelegate.swift similarity index 100% rename from example/ios/Runner/AppDelegate.swift rename to examples/payments/ios/Runner/AppDelegate.swift diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to examples/payments/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/examples/payments/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to examples/payments/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/examples/payments/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from example/ios/Runner/Base.lproj/Main.storyboard rename to examples/payments/ios/Runner/Base.lproj/Main.storyboard diff --git a/examples/payments/ios/Runner/Info.plist b/examples/payments/ios/Runner/Info.plist new file mode 100644 index 0000000..a9528be --- /dev/null +++ b/examples/payments/ios/Runner/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_klarna_inapp_sdk_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + io.flutter.embedded_views_preview + + + diff --git a/example/ios/Runner/Runner-Bridging-Header.h b/examples/payments/ios/Runner/Runner-Bridging-Header.h similarity index 100% rename from example/ios/Runner/Runner-Bridging-Header.h rename to examples/payments/ios/Runner/Runner-Bridging-Header.h diff --git a/examples/payments/lib/main.dart b/examples/payments/lib/main.dart new file mode 100644 index 0000000..af0e272 --- /dev/null +++ b/examples/payments/lib/main.dart @@ -0,0 +1,229 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_klarna_inapp_sdk/klarna_payment_view.dart'; +import 'package:flutter_klarna_inapp_sdk/klarna_payment_sdk_error.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: new Builder(builder: (BuildContext context) { + return new Scaffold( + appBar: AppBar( + title: const Text('Flutter Klarna In-App SDK Example'), + ), + body: new Builder(builder: (BuildContext context) { + return SingleChildScrollView( + child: Container( + child: Column( + children: [ + PaymentOptionsList(), + ], + ), + ), + ); + })); + }), + ); + } +} + +class PaymentOptionsList extends StatefulWidget { + PaymentOptionsList({Key key}) : super(key: key); + + @override + _PaymentOptionsListState createState() => _PaymentOptionsListState(); +} + +class _PaymentOptionsListState extends State { + final String clientToken = + "eyJhbGciOiJSUzI1NiIsImtpZCI6IjgyMzA1ZWJjLWI4MTEtMzYzNy1hYTRjLTY2ZWNhMTg3NGYzZCJ9.eyJzZXNzaW9uX2lkIjoiNWJiNmI2MDgtNmY0MS0zYjliLTljYTMtYTI2NzJjM2VmYTZmIiwiYmFzZV91cmwiOiJodHRwczovL2pzLnBsYXlncm91bmQua2xhcm5hLmNvbS9ldS9rcCIsImRlc2lnbiI6ImtsYXJuYSIsImxhbmd1YWdlIjoiZW4iLCJwdXJjaGFzZV9jb3VudHJ5IjoiREUiLCJlbnZpcm9ubWVudCI6InBsYXlncm91bmQiLCJtZXJjaGFudF9uYW1lIjoiWW91ciBidXNpbmVzcyBuYW1lIiwic2Vzc2lvbl90eXBlIjoiUEFZTUVOVFMiLCJjbGllbnRfZXZlbnRfYmFzZV91cmwiOiJodHRwczovL2V1LnBsYXlncm91bmQua2xhcm5hZXZ0LmNvbSIsInNjaGVtZSI6dHJ1ZSwiZXhwZXJpbWVudHMiOlt7Im5hbWUiOiJpbi1hcHAtc2RrLWNhcmQtc2Nhbm5pbmciLCJ2YXJpYXRlIjoiY2FyZC1zY2FubmluZy1lbmFibGUiLCJwYXJhbWV0ZXJzIjp7InZhcmlhdGVfaWQiOiJjYXJkLXNjYW5uaW5nLWVuYWJsZSJ9fV0sInJlZ2lvbiI6ImV1IiwidWFfZW5hYmxlZF9hbmRfb25lX3BtIjpmYWxzZX0.hQzt9-hdxPm2gqFrjU8B7b-RJtAZgt3S7_RrZVgP9BLzDqyyi387MvqRMaGzXVdaOiqNXmRO1I1piougeDyD5TiuDNj2HHJdNXoa3g_wS8zFFmvpyWKaCxjixTGH16uhMigj4Oy_fUVw3wy9HoqooDl9kF2NFCkdQND6VW_ROk6_-bVAiAJ3--gIgHEL8gL6KrkNE7at_owD3iBQfnHz4WftKrmVP0QF0tId3vdua7_qXbFIIl99wOM8JO-Tz2V6q14FhimNEO_Nm7oNOwD7gNjTksAR1RrGu90z16zrbwZwPDzZCLCEmGKOvLAZHrLPgVR6aNE4_lAozTZhlkT9kw"; + + List itemData = [ + ItemModel(headerItem: 'Pay Now'), + ItemModel(headerItem: 'Pay Later'), + ItemModel(headerItem: 'Slice It'), + ]; + + KlarnaPaymentController payNowController; + KlarnaPaymentController payLaterController; + KlarnaPaymentController sliceItController; + + int selectedIndex; + + @override + Widget build(BuildContext context) { + final paynow = KlarnaPaymentView.payNow( + onCreated: (controller) async { + this.payNowController = controller; + await controller.initialize( + clientToken: clientToken, returnUrl: "returnUrl://"); + }, + onAuthorized: onAuthorized, + onErrorOccurred: onErrorOccured, + onFinalized: onFinalized, + onInitialized: onInitialized, + onLoadPaymentReview: onLoadPaymentReview, + onLoaded: onLoaded, + onReauthorized: onReauthorized, + ); + + final paylater = KlarnaPaymentView.payLater( + onCreated: (controller) async { + this.payLaterController = controller; + await controller.initialize( + clientToken: clientToken, returnUrl: "returnUrl://"); + }, + onAuthorized: onAuthorized, + onErrorOccurred: onErrorOccured, + onFinalized: onFinalized, + onInitialized: onInitialized, + onLoadPaymentReview: onLoadPaymentReview, + onLoaded: onLoaded, + onReauthorized: onReauthorized, + ); + + final sliceit = KlarnaPaymentView.sliceIt( + onCreated: (controller) async { + this.sliceItController = controller; + await controller.initialize( + clientToken: clientToken, returnUrl: "returnUrl://"); + }, + onAuthorized: onAuthorized, + onErrorOccurred: onErrorOccured, + onFinalized: onFinalized, + onInitialized: onInitialized, + onLoadPaymentReview: onLoadPaymentReview, + onLoaded: onLoaded, + onReauthorized: onReauthorized, + ); + + final categories = [paynow, paylater, sliceit]; + + return Column( + children: [ + Container( + padding: EdgeInsets.all(10), + child: ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: itemData.length, + itemBuilder: (BuildContext context, int index) { + return ExpansionPanelList.radio( + animationDuration: Duration(milliseconds: 500), + children: [ + ExpansionPanelRadio( + value: index, + headerBuilder: (BuildContext context, bool isExpanded) { + return Container( + padding: EdgeInsets.all(10), + child: Text( + itemData[index].headerItem, + style: TextStyle( + fontSize: 18, + ), + ), + ); + }, + body: Container( + padding: EdgeInsets.all(10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + categories[index], + ], + ), + ), + canTapOnHeader: true, + ) + ], + expansionCallback: (int item, bool status) { + setState(() { + itemData[index].expanded = !itemData[index].expanded; + selectedIndex = index; + }); + if (!status) { + final controllers = [ + this.payNowController, + this.payLaterController, + this.sliceItController + ]; + controllers[index].load(); + } + }, + ); + }, + ), + ), + Container( + child: RaisedButton( + color: Colors.orange, + onPressed: () { + final controllers = [ + this.payNowController, + this.payLaterController, + this.sliceItController + ]; + controllers[selectedIndex].authorize(autoFinalize: false); + }, + child: Text( + "Pay", + style: TextStyle(color: Colors.white), + )), + ), + ], + ); + } + + void onAuthorized(KlarnaPaymentController controller, bool approved, + String authToken, bool finalizeRequired) { + print( + "authorized approved: $approved, authToken: $authToken, finalizeRequired: $finalizeRequired"); + } + + void onErrorOccured( + KlarnaPaymentController controller, KlarnaPaymentSDKError error) { + print("error occured $error"); + } + + void onFinalized( + KlarnaPaymentController controller, bool approved, String authToken) { + print("finalized approved: $approved, authToken: $authToken"); + } + + void onInitialized(KlarnaPaymentController controller) { + print("initialized"); + } + + void onLoadPaymentReview(KlarnaPaymentController controller, bool showForm) { + print("payment review loaded showForm: $showForm"); + } + + void onLoaded(KlarnaPaymentController controller) { + print("loaded"); + } + + void onReauthorized( + KlarnaPaymentController controller, bool approved, String authToken) { + print("reauthorized approved: $approved, authToken: $authToken"); + } +} + +class ItemModel { + bool expanded; + String headerItem; + + ItemModel({this.expanded: false, this.headerItem}); +} diff --git a/example/pubspec.lock b/examples/payments/pubspec.lock similarity index 99% rename from example/pubspec.lock rename to examples/payments/pubspec.lock index b2b8ecf..c414ba0 100644 --- a/example/pubspec.lock +++ b/examples/payments/pubspec.lock @@ -72,7 +72,7 @@ packages: flutter_klarna_inapp_sdk: dependency: "direct dev" description: - path: ".." + path: "../.." relative: true source: path version: "0.0.1" diff --git a/example/pubspec.yaml b/examples/payments/pubspec.yaml similarity index 99% rename from example/pubspec.yaml rename to examples/payments/pubspec.yaml index cf7eec1..406c5b6 100644 --- a/example/pubspec.yaml +++ b/examples/payments/pubspec.yaml @@ -18,7 +18,7 @@ dev_dependencies: sdk: flutter flutter_klarna_inapp_sdk: - path: ../ + path: ../../ # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/example/test/widget_test.dart b/examples/payments/test/widget_test.dart similarity index 81% rename from example/test/widget_test.dart rename to examples/payments/test/widget_test.dart index 685e5ee..639a52f 100644 --- a/example/test/widget_test.dart +++ b/examples/payments/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter_klarna_inapp_sdk_example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { @@ -18,8 +18,8 @@ void main() { // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + (Widget widget) => + widget is Text && widget.data.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/examples/post_purchase_experience/.gitignore b/examples/post_purchase_experience/.gitignore new file mode 100644 index 0000000..ae1f183 --- /dev/null +++ b/examples/post_purchase_experience/.gitignore @@ -0,0 +1,37 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/examples/post_purchase_experience/.metadata b/examples/post_purchase_experience/.metadata new file mode 100644 index 0000000..4adf4bf --- /dev/null +++ b/examples/post_purchase_experience/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 + channel: stable + +project_type: app diff --git a/examples/post_purchase_experience/README.md b/examples/post_purchase_experience/README.md new file mode 100644 index 0000000..953b278 --- /dev/null +++ b/examples/post_purchase_experience/README.md @@ -0,0 +1,16 @@ +# flutter_klarna_inapp_sdk_example + +Demonstrates how to use the flutter_klarna_inapp_sdk plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/examples/post_purchase_experience/android/.gitignore b/examples/post_purchase_experience/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/examples/post_purchase_experience/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/example/android/app/build.gradle b/examples/post_purchase_experience/android/app/build.gradle similarity index 100% rename from example/android/app/build.gradle rename to examples/post_purchase_experience/android/app/build.gradle diff --git a/examples/post_purchase_experience/android/app/src/debug/AndroidManifest.xml b/examples/post_purchase_experience/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..547d56f --- /dev/null +++ b/examples/post_purchase_experience/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/examples/post_purchase_experience/android/app/src/main/AndroidManifest.xml b/examples/post_purchase_experience/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d10e5a1 --- /dev/null +++ b/examples/post_purchase_experience/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + diff --git a/examples/post_purchase_experience/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt b/examples/post_purchase_experience/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt new file mode 100644 index 0000000..afb9254 --- /dev/null +++ b/examples/post_purchase_experience/android/app/src/main/kotlin/com/klarna/inapp/sdk/flutter_klarna_inapp_sdk_example/MainActivity.kt @@ -0,0 +1,12 @@ +package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk_example + +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity: FlutterActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/examples/post_purchase_experience/android/app/src/main/res/drawable/launch_background.xml b/examples/post_purchase_experience/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/examples/post_purchase_experience/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/examples/post_purchase_experience/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/post_purchase_experience/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/examples/post_purchase_experience/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/examples/post_purchase_experience/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/post_purchase_experience/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/examples/post_purchase_experience/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/examples/post_purchase_experience/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/post_purchase_experience/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/examples/post_purchase_experience/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/examples/post_purchase_experience/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/post_purchase_experience/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/examples/post_purchase_experience/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/examples/post_purchase_experience/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/post_purchase_experience/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/examples/post_purchase_experience/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/examples/post_purchase_experience/android/app/src/main/res/values/styles.xml b/examples/post_purchase_experience/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/examples/post_purchase_experience/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/examples/post_purchase_experience/android/app/src/profile/AndroidManifest.xml b/examples/post_purchase_experience/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..547d56f --- /dev/null +++ b/examples/post_purchase_experience/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/examples/post_purchase_experience/android/build.gradle b/examples/post_purchase_experience/android/build.gradle new file mode 100644 index 0000000..45d37ba --- /dev/null +++ b/examples/post_purchase_experience/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.3.72' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/examples/post_purchase_experience/android/gradle.properties b/examples/post_purchase_experience/android/gradle.properties new file mode 100644 index 0000000..4d5ddfb --- /dev/null +++ b/examples/post_purchase_experience/android/gradle.properties @@ -0,0 +1,5 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true +kotlin.code.style=official \ No newline at end of file diff --git a/examples/post_purchase_experience/android/gradle/wrapper/gradle-wrapper.properties b/examples/post_purchase_experience/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..bc24dcf --- /dev/null +++ b/examples/post_purchase_experience/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/examples/post_purchase_experience/android/settings.gradle b/examples/post_purchase_experience/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/examples/post_purchase_experience/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/examples/post_purchase_experience/ios/.gitignore b/examples/post_purchase_experience/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/examples/post_purchase_experience/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/examples/post_purchase_experience/ios/Flutter/AppFrameworkInfo.plist b/examples/post_purchase_experience/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..6b4c0f7 --- /dev/null +++ b/examples/post_purchase_experience/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/examples/post_purchase_experience/ios/Flutter/Debug.xcconfig b/examples/post_purchase_experience/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..e8efba1 --- /dev/null +++ b/examples/post_purchase_experience/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/examples/post_purchase_experience/ios/Flutter/Release.xcconfig b/examples/post_purchase_experience/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/examples/post_purchase_experience/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/examples/post_purchase_experience/ios/Podfile b/examples/post_purchase_experience/ios/Podfile new file mode 100644 index 0000000..ab7d5b4 --- /dev/null +++ b/examples/post_purchase_experience/ios/Podfile @@ -0,0 +1,90 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '10.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + generated_key_values = {} + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) do |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + generated_key_values[podname] = podpath + else + puts "Invalid plugin specification: #{line}" + end + end + generated_key_values +end + +target 'Runner' do + use_frameworks! + use_modular_headers! + + # Flutter Pod + + copied_flutter_dir = File.join(__dir__, 'Flutter') + copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') + copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') + unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) + # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. + # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + + generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') + unless File.exist?(generated_xcode_build_settings_path) + raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) + cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + + unless File.exist?(copied_framework_path) + FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) + end + unless File.exist?(copied_podspec_path) + FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) + end + end + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' + + # Plugin Pods + + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.each do |name, path| + symlink = File.join('.symlinks', 'plugins', name) + File.symlink(path, symlink) + pod name, :path => File.join(symlink, 'ios') + end +end + +# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. +install! 'cocoapods', :disable_input_output_paths => true + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/example/ios/Podfile.lock b/examples/post_purchase_experience/ios/Podfile.lock similarity index 100% rename from example/ios/Podfile.lock rename to examples/post_purchase_experience/ios/Podfile.lock diff --git a/examples/post_purchase_experience/ios/Runner.xcodeproj/project.pbxproj b/examples/post_purchase_experience/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b5bc3d5 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,571 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + F104BFB5556E6A6832126F91 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8BFB70EE8C779E437BDC793 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 293F7DC4B1EA26E0491ED791 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A762717D72802B999CBB6DAE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + D8A17D28E26B0DA7CCD2CDE8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + D8BFB70EE8C779E437BDC793 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F104BFB5556E6A6832126F91 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 40265536B07BDE3F3BB1591A /* Pods */ = { + isa = PBXGroup; + children = ( + A762717D72802B999CBB6DAE /* Pods-Runner.debug.xcconfig */, + D8A17D28E26B0DA7CCD2CDE8 /* Pods-Runner.release.xcconfig */, + 293F7DC4B1EA26E0491ED791 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 40265536B07BDE3F3BB1591A /* Pods */, + E005B20E771C86F3AC9AC776 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + E005B20E771C86F3AC9AC776 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D8BFB70EE8C779E437BDC793 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 567CBE310842AD241AF51EF7 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + D515E90F1FA4D25444645704 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n"; + }; + 567CBE310842AD241AF51EF7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + D515E90F1FA4D25444645704 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.klarna.inapp.sdk.flutterKlarnaInappSdkExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.klarna.inapp.sdk.flutterKlarnaInappSdkExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.klarna.inapp.sdk.flutterKlarnaInappSdkExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/examples/post_purchase_experience/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/post_purchase_experience/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/post_purchase_experience/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/post_purchase_experience/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/post_purchase_experience/ios/Runner.xcworkspace/contents.xcworkspacedata b/examples/post_purchase_experience/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/examples/post_purchase_experience/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/post_purchase_experience/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/post_purchase_experience/ios/Runner/AppDelegate.swift b/examples/post_purchase_experience/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/examples/post_purchase_experience/ios/Runner/Base.lproj/LaunchScreen.storyboard b/examples/post_purchase_experience/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/post_purchase_experience/ios/Runner/Base.lproj/Main.storyboard b/examples/post_purchase_experience/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Info.plist b/examples/post_purchase_experience/ios/Runner/Info.plist similarity index 100% rename from example/ios/Runner/Info.plist rename to examples/post_purchase_experience/ios/Runner/Info.plist diff --git a/examples/post_purchase_experience/ios/Runner/Runner-Bridging-Header.h b/examples/post_purchase_experience/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..7335fdf --- /dev/null +++ b/examples/post_purchase_experience/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/example/lib/main.dart b/examples/post_purchase_experience/lib/main.dart similarity index 100% rename from example/lib/main.dart rename to examples/post_purchase_experience/lib/main.dart diff --git a/examples/post_purchase_experience/pubspec.lock b/examples/post_purchase_experience/pubspec.lock new file mode 100644 index 0000000..c414ba0 --- /dev/null +++ b/examples/post_purchase_experience/pubspec.lock @@ -0,0 +1,195 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.3" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.12" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_klarna_inapp_sdk: + dependency: "direct dev" + description: + path: "../.." + relative: true + source: path + version: "0.0.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.12" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.6" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.8" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.15" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.1" +sdks: + dart: ">=2.6.0 <3.0.0" diff --git a/examples/post_purchase_experience/pubspec.yaml b/examples/post_purchase_experience/pubspec.yaml new file mode 100644 index 0000000..97773b9 --- /dev/null +++ b/examples/post_purchase_experience/pubspec.yaml @@ -0,0 +1,63 @@ +name: flutter_klarna_inapp_sdk_post_purchase_example +description: Demonstrates how to use the flutter_klarna_inapp_sdk plugin. +publish_to: 'none' + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_klarna_inapp_sdk: + path: ../../ + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/examples/post_purchase_experience/test/widget_test.dart b/examples/post_purchase_experience/test/widget_test.dart new file mode 100644 index 0000000..639a52f --- /dev/null +++ b/examples/post_purchase_experience/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../lib/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => + widget is Text && widget.data.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/ios/Classes/Payment/PaymentView.swift b/ios/Classes/Payment/PaymentView.swift new file mode 100644 index 0000000..771043d --- /dev/null +++ b/ios/Classes/Payment/PaymentView.swift @@ -0,0 +1,153 @@ +import Flutter +import UIKit +import KlarnaMobileSDK + +class PaymentViewFactory: NSObject, FlutterPlatformViewFactory { + private var messenger: FlutterBinaryMessenger + + init(messenger: FlutterBinaryMessenger) { + self.messenger = messenger + super.init() + } + + func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { + FlutterStandardMessageCodec.sharedInstance() + } + + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return PaymentView( + frame: frame, + viewIdentifier: viewId, + arguments: args as? Dictionary ?? [:], + binaryMessenger: messenger) + } +} + +class PaymentView: NSObject, FlutterPlatformView { + private var _view: UIView + private var klarnaHeightConstraint: NSLayoutConstraint? + private var methodChannel: FlutterMethodChannel + private var callbackMethodChannel: FlutterMethodChannel + private var paymentView: KlarnaPaymentView? + private var category: String + + init( + frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Dictionary, + binaryMessenger messenger: FlutterBinaryMessenger? + ) { + let channelName = "plugins/klarna_payment_view_\(viewId)" + self.methodChannel = FlutterMethodChannel(name: channelName, binaryMessenger: messenger!) + self.callbackMethodChannel = FlutterMethodChannel(name: "klarna_payment_callbacks", binaryMessenger: messenger!) + self.category = args["category"] as! String + callbackMethodChannel.invokeMethod("onInitialized", arguments: nil) + + _view = UIView() + + super.init() + + self.methodChannel.setMethodCallHandler(onMethodCall) + + createPaymentView(view: _view) + } + + func view() -> UIView { + return _view + } + + func onMethodCall(_ methodCall: FlutterMethodCall, result: FlutterResult) { + switch methodCall.method { + case "initialize": + self.initialize(call: methodCall, result: result) + case "load": + self.load(call: methodCall, result: result) + case "authorize": + self.authorize(call: methodCall, result: result) + default: result(FlutterMethodNotImplemented) + } + } + + func initialize(call: FlutterMethodCall, result: FlutterResult) -> Void { + let args = call.arguments as? [String: Any] ?? [:] + let clientToken = args["clientToken"] as! String + let returnUrl = args["returnUrl"] as! String + paymentView!.initialize(clientToken: clientToken, returnUrl: URL(string: returnUrl)!) + } + + func load(call: FlutterMethodCall, result: FlutterResult) -> Void { + let args = call.arguments as? [String: Any] ?? [:] + let loadArgs = args["args"] as? String + paymentView!.load(jsonData: loadArgs) + } + + func authorize(call: FlutterMethodCall, result: FlutterResult) -> Void { + let args = call.arguments as? [String: Any] ?? [:] + let autoFinalize = args["autoFinalize"] as! Bool + let sessionData = args["sessionData"] as? String + paymentView!.authorize(autoFinalize: autoFinalize, jsonData: sessionData) + } + + func createPaymentView(view _view: UIView){ + self.paymentView = KlarnaPaymentView(category: category, eventListener: self) + + paymentView!.translatesAutoresizingMaskIntoConstraints = false + self.klarnaHeightConstraint = paymentView!.heightAnchor.constraint(equalToConstant: 0) + klarnaHeightConstraint?.isActive = true + + _view.addSubview(paymentView!) + + NSLayoutConstraint.activate([ + paymentView!.widthAnchor.constraint(equalTo: _view.widthAnchor), + paymentView!.centerXAnchor.constraint(equalTo: _view.centerXAnchor) + ]) + } +} + +extension PaymentView: KlarnaPaymentEventListener { + func klarnaResized(paymentView: KlarnaPaymentView, to newHeight: CGFloat) { + self.klarnaHeightConstraint!.constant = newHeight + } + + func klarnaInitialized(paymentView: KlarnaPaymentView) { + self.methodChannel.invokeMethod("onInitialized", arguments: nil) + } + + func klarnaLoaded(paymentView: KlarnaPaymentView) { + self.methodChannel.invokeMethod("onLoaded", arguments: nil) + } + + func klarnaLoadedPaymentReview(paymentView: KlarnaPaymentView) { + self.methodChannel.invokeMethod("onLoadPaymentReview", arguments: nil) + } + + func klarnaAuthorized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?, finalizeRequired: Bool) { + let args: [String: Any?] = ["approved": approved, "authToken": authToken, "finalizeRequired": finalizeRequired] + self.methodChannel.invokeMethod("onAuthorized", arguments: args) + } + + func klarnaReauthorized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?) { + let args: [String: Any?] = ["approved": approved, "authToken": authToken] + self.methodChannel.invokeMethod("onReauthorized", arguments: args) + } + + func klarnaFinalized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?) { + let args: [String: Any?] = ["approved": approved, "authToken": authToken] + self.methodChannel.invokeMethod("onFinalized", arguments: args) + } + + func klarnaFailed(inPaymentView: KlarnaPaymentView, withError: KlarnaPaymentError){ + let args: [String: Any?] = [ + "invalidFields": withError.invalidFields, + "action": withError.action, + "isFatal": withError.isFatal, + "name": withError.name, + "message": withError.message + ] + self.methodChannel.invokeMethod("onErrorOccurred", arguments: args) + } +} \ No newline at end of file diff --git a/ios/Classes/Payment/PaymentViewPlugin.swift b/ios/Classes/Payment/PaymentViewPlugin.swift new file mode 100644 index 0000000..989d59e --- /dev/null +++ b/ios/Classes/Payment/PaymentViewPlugin.swift @@ -0,0 +1,9 @@ +import Flutter +import UIKit + +class PaymentViewPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let factory = PaymentViewFactory(messenger: registrar.messenger()) + registrar.register(factory, withId: "plugins/klarna_payment_view") + } +} diff --git a/ios/Classes/SwiftFlutterKlarnaInappSdk.swift b/ios/Classes/SwiftFlutterKlarnaInappSdk.swift index 1913213..19a502f 100644 --- a/ios/Classes/SwiftFlutterKlarnaInappSdk.swift +++ b/ios/Classes/SwiftFlutterKlarnaInappSdk.swift @@ -18,6 +18,8 @@ public class SwiftFlutterKlarnaInappSdk: NSObject, FlutterPlugin { let channel = FlutterEventChannel(name: key, binaryMessenger: messenger) channel.setStreamHandler(value) } + + PaymentViewPlugin.register(with: registrar) } static func getMethodHandlerMap() -> [String: FlutterPlugin] { diff --git a/lib/klarna_payment_sdk_error.dart b/lib/klarna_payment_sdk_error.dart new file mode 100644 index 0000000..fbb077a --- /dev/null +++ b/lib/klarna_payment_sdk_error.dart @@ -0,0 +1,15 @@ +class KlarnaPaymentSDKError { + final String message; + final String action; + final String name; + final bool isFatal; + final List invalidFields; + + const KlarnaPaymentSDKError( + {this.message, this.action, this.name, this.invalidFields, this.isFatal}); + + @override + String toString() { + return "message: $message, action: $action, name: $name, isFatal: $isFatal, invalidFields: $invalidFields"; + } +} diff --git a/lib/klarna_payment_view.dart b/lib/klarna_payment_view.dart new file mode 100644 index 0000000..66edd56 --- /dev/null +++ b/lib/klarna_payment_view.dart @@ -0,0 +1,189 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_klarna_inapp_sdk/klarna_payment_sdk_error.dart'; + +const KlarnaPaymentCategoryPayNow = "pay_now"; +const KlarnaPaymentCategoryPayLater = "pay_later"; +const KlarnaPaymentCategorySliceIt = "pay_over_time"; + +typedef OnCreatedCallback = void Function(KlarnaPaymentController controller); + +typedef OnAuthorizedCallback = void Function(KlarnaPaymentController controller, + bool approved, String authToken, bool finalizeRequired); +typedef OnErrorOccurredCallback = void Function( + KlarnaPaymentController controller, KlarnaPaymentSDKError error); +typedef OnFinalizedCallback = void Function( + KlarnaPaymentController controller, bool approved, String authToken); +typedef OnInitializedCallback = void Function( + KlarnaPaymentController controller); +typedef OnLoadPaymentReviewCallback = void Function( + KlarnaPaymentController controller, bool showForm); +typedef OnLoadedCallback = void Function(KlarnaPaymentController controller); +typedef OnReauthorizedCallback = void Function( + KlarnaPaymentController controller, bool approved, String authToken); + +class KlarnaPaymentView extends StatelessWidget { + final String category; + final OnCreatedCallback onCreated; + final OnAuthorizedCallback onAuthorized; + final OnErrorOccurredCallback onErrorOccurred; + final OnFinalizedCallback onFinalized; + final OnInitializedCallback onInitialized; + final OnLoadPaymentReviewCallback onLoadPaymentReview; + final OnLoadedCallback onLoaded; + final OnReauthorizedCallback onReauthorized; + KlarnaPaymentController _controller; + + KlarnaPaymentView({ + Key key, + @required this.category, + this.onCreated, + this.onAuthorized, + this.onErrorOccurred, + this.onFinalized, + this.onInitialized, + this.onLoadPaymentReview, + this.onLoaded, + this.onReauthorized, + }) : super(key: key); + + KlarnaPaymentView.payNow({ + Key key, + this.onCreated, + this.onAuthorized, + this.onErrorOccurred, + this.onFinalized, + this.onInitialized, + this.onLoadPaymentReview, + this.onLoaded, + this.onReauthorized, + }) : category = KlarnaPaymentCategoryPayNow, + super(key: key); + + KlarnaPaymentView.payLater({ + Key key, + this.onCreated, + this.onAuthorized, + this.onErrorOccurred, + this.onFinalized, + this.onInitialized, + this.onLoadPaymentReview, + this.onLoaded, + this.onReauthorized, + }) : category = KlarnaPaymentCategoryPayLater, + super(key: key); + + KlarnaPaymentView.sliceIt({ + Key key, + this.onCreated, + this.onAuthorized, + this.onErrorOccurred, + this.onFinalized, + this.onInitialized, + this.onLoadPaymentReview, + this.onLoaded, + this.onReauthorized, + }) : category = KlarnaPaymentCategorySliceIt, + super(key: key); + + @override + Widget build(BuildContext context) { + if (defaultTargetPlatform == TargetPlatform.android) { + return Column( + children: [ + Container( + height: 300, + child: AndroidView( + viewType: 'plugins/klarna_payment_view', + onPlatformViewCreated: _onPlatformViewCreated, + creationParamsCodec: const StandardMessageCodec(), + creationParams: {"category": category}, + ), + ), + ], + ); + } + if (defaultTargetPlatform == TargetPlatform.iOS) { + return Container( + height: 300, + child: UiKitView( + viewType: 'plugins/klarna_payment_view', + onPlatformViewCreated: _onPlatformViewCreated, + layoutDirection: TextDirection.ltr, + creationParams: {"category": category}, + creationParamsCodec: const StandardMessageCodec(), + ), + ); + } + + return Text("Platform not supported."); + } + + Future _onPlatformViewCreated(int id) async { + final methodChannel = MethodChannel("plugins/klarna_payment_view_$id"); + methodChannel.setMethodCallHandler(this._callbackHandler); + final controller = KlarnaPaymentController._(id); + onCreated(controller); + + this._controller = controller; + } + + Future _callbackHandler(MethodCall call) async { + final args = call.arguments; + switch (call.method) { + case "onAuthorized": + onAuthorized?.call(this._controller, args["approved"], + args["authToken"], args["finalizeRequired"]); + break; + case "onErrorOccurred": + final error = KlarnaPaymentSDKError( + action: args["action"], + invalidFields: args["invalidFields"], + isFatal: args["isFatal"], + message: args["message"], + name: args["name"], + ); + onErrorOccurred?.call(this._controller, error); + break; + case "onFinalized": + onFinalized?.call( + this._controller, args["approved"], args["authToken"]); + break; + case "onInitialized": + onInitialized?.call(this._controller); + break; + case "onLoadPaymentReview": + onLoadPaymentReview?.call(this._controller, args["showForm"] ?? false); + break; + case "onLoaded": + onLoaded?.call(this._controller); + break; + case "onReauthorized": + onReauthorized?.call( + this._controller, args["approved"], args["authToken"]); + } + } +} + +class KlarnaPaymentController { + KlarnaPaymentController._(int id) + : _channel = MethodChannel('plugins/klarna_payment_view_$id'); + + final MethodChannel _channel; + + Future initialize({String clientToken, String returnUrl}) async { + return _channel.invokeMethod( + 'initialize', {"clientToken": clientToken, "returnUrl": returnUrl}); + } + + Future load({String args}) async { + return _channel.invokeMethod('load', {"args": args}); + } + + Future authorize( + {@required bool autoFinalize, String sessionData}) async { + return _channel.invokeMethod('authorize', + {"autoFinalize": autoFinalize, "sessionData": sessionData}); + } +}