SlideShare a Scribd company logo
Native Payment - Part III
Before We Begin
✦ Send a build with include source and open the
source in the native IDE then do the implementation
there, once done copy the code back to the native
directory
✦ Be aware of threads. Go into the native thread and
don’t forget to go back to the EDT in the callback!
© Codename One 2017 all rights reserved
final Activity act = AndroidNativeUtil.getActivity();
act.runOnUiThread(new Runnable() {
public void run() {
DropInRequest dropInRequest = new DropInRequest()
.clientToken(param);
AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act),
new IntentResultListener() {
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
BraintreePaymentCallback.onPurchaseSuccess(
result.getPaymentMethodNonce().getNonce());
} else if (resultCode == Activity.RESULT_CANCELED) {
BraintreePaymentCallback.onPurchaseCancel();
} else {
Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
BraintreePaymentCallback.onPurchaseFail(error.toString());
Log.e(error);
Log.sendLog();
}
}
});
}
});
Android
final Activity act = AndroidNativeUtil.getActivity();
act.runOnUiThread(new Runnable() {
public void run() {
DropInRequest dropInRequest = new DropInRequest()
.clientToken(param);
AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act),
new IntentResultListener() {
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
BraintreePaymentCallback.onPurchaseSuccess(
result.getPaymentMethodNonce().getNonce());
} else if (resultCode == Activity.RESULT_CANCELED) {
BraintreePaymentCallback.onPurchaseCancel();
} else {
Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
BraintreePaymentCallback.onPurchaseFail(error.toString());
Log.e(error);
Log.sendLog();
}
}
});
}
});
Android
Activity
Almost all Android Sample code
assumes this==activity. In a native
interface that just isn’t true which is
why in most cases where this is
referenced you can just do getActivity
using AndroidNative Util
final Activity act = AndroidNativeUtil.getActivity();
act.runOnUiThread(new Runnable() {
public void run() {
DropInRequest dropInRequest = new DropInRequest()
.clientToken(param);
AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act),
new IntentResultListener() {
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
BraintreePaymentCallback.onPurchaseSuccess(
result.getPaymentMethodNonce().getNonce());
} else if (resultCode == Activity.RESULT_CANCELED) {
BraintreePaymentCallback.onPurchaseCancel();
} else {
Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
BraintreePaymentCallback.onPurchaseFail(error.toString());
Log.e(error);
Log.sendLog();
}
}
});
}
});
Android
UI Thread
Most Android sample code assumes
you are on the Android equivalent of the
EDT (UI thread). We are on the
Codename One EDT or a Codename
One thread in a native interface so it’s
best to do something like this unless
you need a synchronous call
final Activity act = AndroidNativeUtil.getActivity();
act.runOnUiThread(new Runnable() {
public void run() {
DropInRequest dropInRequest = new DropInRequest()
.clientToken(param);
AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act),
new IntentResultListener() {
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
BraintreePaymentCallback.onPurchaseSuccess(
result.getPaymentMethodNonce().getNonce());
} else if (resultCode == Activity.RESULT_CANCELED) {
BraintreePaymentCallback.onPurchaseCancel();
} else {
Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
BraintreePaymentCallback.onPurchaseFail(error.toString());
Log.e(error);
Log.sendLog();
}
}
});
}
});
Android
startActivityForResult
This is a very common method of
activity but grabbing the result isn’t
intuitive which is why we have this
method
final Activity act = AndroidNativeUtil.getActivity();
act.runOnUiThread(new Runnable() {
public void run() {
DropInRequest dropInRequest = new DropInRequest()
.clientToken(param);
AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act),
new IntentResultListener() {
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
BraintreePaymentCallback.onPurchaseSuccess(
result.getPaymentMethodNonce().getNonce());
} else if (resultCode == Activity.RESULT_CANCELED) {
BraintreePaymentCallback.onPurchaseCancel();
} else {
Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
BraintreePaymentCallback.onPurchaseFail(error.toString());
Log.e(error);
Log.sendLog();
}
}
});
}
});
Android
Callbacks & API
On Android we can access the
Codename One API directly since it’s all
just Java…
dispatch_async(dispatch_get_main_queue(), ^{
BTDropInRequest *request = [[BTDropInRequest alloc] init];
BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request
handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError *
_Nullable error) {
if (error != nil) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST
ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription]));
} else if (result.cancelled) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE
_ARG);
} else {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET
_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce));
}
[controller dismissViewControllerAnimated:YES completion:nil];
}];
[[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES
completion:nil];
});
iOS
dispatch_async(dispatch_get_main_queue(), ^{
BTDropInRequest *request = [[BTDropInRequest alloc] init];
BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request
handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError *
_Nullable error) {
if (error != nil) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST
ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription]));
} else if (result.cancelled) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE
_ARG);
} else {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET
_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce));
}
[controller dismissViewControllerAnimated:YES completion:nil];
}];
[[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES
completion:nil];
});
iOS
iOS EDT
iOS is very sensitive to EDT violations.
It’s really important to use it’s main
queue (native EDT) for everything
related to UI
dispatch_async(dispatch_get_main_queue(), ^{
BTDropInRequest *request = [[BTDropInRequest alloc] init];
BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request
handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError *
_Nullable error) {
if (error != nil) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST
ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription]));
} else if (result.cancelled) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE
_ARG);
} else {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET
_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce));
}
[controller dismissViewControllerAnimated:YES completion:nil];
}];
[[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES
completion:nil];
});
iOS
Self
Self is the Objective-C equivalent of
this. In the original code self was used
as it was assumed to be a Controller
(commonly used iOS abstraction) when
you need a controller you can use this
syntax
dispatch_async(dispatch_get_main_queue(), ^{
BTDropInRequest *request = [[BTDropInRequest alloc] init];
BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request
handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError *
_Nullable error) {
if (error != nil) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST
ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription]));
} else if (result.cancelled) {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE
_ARG);
} else {
com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET
_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce));
}
[controller dismissViewControllerAnimated:YES completion:nil];
}];
[[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES
completion:nil];
});
iOS
Callbacks
Callbacks to Java code are complex
and have a slightly different syntax
when calling to a no-args method but
IDE completion should help…
What did we learn?
✦Native interfaces aren’t trivial, but are doable when
we overcome the pitfalls and use Google
aggressively
✦Error logs on Android are painful and we need to
develop reading skill to go thru them
✦Use native IDE’s to develop the native code and
shorten the back and forth cycles
Thank You!

More Related Content

PDF
Android Best Practices
PDF
PDF
Slightly Advanced Android Wear ;)
PDF
[FEConf Korea 2017]Angular 컴포넌트 대화법
PDF
Road to react hooks
PPTX
Working effectively with legacy code
PPTX
An intro to cqrs
KEY
Android workshop
Android Best Practices
Slightly Advanced Android Wear ;)
[FEConf Korea 2017]Angular 컴포넌트 대화법
Road to react hooks
Working effectively with legacy code
An intro to cqrs
Android workshop

Similar to Native Payment - Part 3.pdf (20)

PPTX
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
PDF
JavaScript Functions
PDF
N Things You Don't Want to Repeat in React Native
PPTX
Imagine a world without mocks
PPTX
Windows Store app using XAML and C#: Enterprise Product Development
KEY
Design Patterns for Tablets and Smartphones
PPTX
Reactive programming every day
PDF
Declarative presentations UIKonf
PDF
The evolution of redux action creators
PDF
Side effects-con-redux
PPTX
Clean Test
PDF
BLoC - Be Reactive in flutter
PDF
mobl
ODP
Ruslan Platonov - Transactions
PPTX
Google Plus SignIn : l'Authentification Google
PDF
JavaScript Core
PPTX
Battle of React State Managers in frontend applications
PPTX
How Reactive do we need to be
PDF
A Journey with React
PPTX
Building an End-to-End AngularJS Application
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
JavaScript Functions
N Things You Don't Want to Repeat in React Native
Imagine a world without mocks
Windows Store app using XAML and C#: Enterprise Product Development
Design Patterns for Tablets and Smartphones
Reactive programming every day
Declarative presentations UIKonf
The evolution of redux action creators
Side effects-con-redux
Clean Test
BLoC - Be Reactive in flutter
mobl
Ruslan Platonov - Transactions
Google Plus SignIn : l'Authentification Google
JavaScript Core
Battle of React State Managers in frontend applications
How Reactive do we need to be
A Journey with React
Building an End-to-End AngularJS Application
Ad

More from ShaiAlmog1 (20)

PDF
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
PDF
create-netflix-clone-06-client-ui.pdf
PDF
create-netflix-clone-01-introduction_transcript.pdf
PDF
create-netflix-clone-02-server_transcript.pdf
PDF
create-netflix-clone-04-server-continued_transcript.pdf
PDF
create-netflix-clone-01-introduction.pdf
PDF
create-netflix-clone-06-client-ui_transcript.pdf
PDF
create-netflix-clone-03-server.pdf
PDF
create-netflix-clone-04-server-continued.pdf
PDF
create-netflix-clone-05-client-model_transcript.pdf
PDF
create-netflix-clone-03-server_transcript.pdf
PDF
create-netflix-clone-02-server.pdf
PDF
create-netflix-clone-05-client-model.pdf
PDF
Creating a Whatsapp Clone - Part II.pdf
PDF
Creating a Whatsapp Clone - Part IX - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part II - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part V - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part IV - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part IV.pdf
PDF
Creating a Whatsapp Clone - Part I - Transcript.pdf
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-01-introduction.pdf
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-03-server.pdf
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-02-server.pdf
create-netflix-clone-05-client-model.pdf
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
Ad

Recently uploaded (20)

PDF
August Patch Tuesday
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Enhancing emotion recognition model for a student engagement use case through...
PPTX
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Tartificialntelligence_presentation.pptx
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
Architecture types and enterprise applications.pdf
PPT
What is a Computer? Input Devices /output devices
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
PPT
Module 1.ppt Iot fundamentals and Architecture
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PPTX
O2C Customer Invoices to Receipt V15A.pptx
PDF
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
PDF
A contest of sentiment analysis: k-nearest neighbor versus neural network
August Patch Tuesday
gpt5_lecture_notes_comprehensive_20250812015547.pdf
A comparative study of natural language inference in Swahili using monolingua...
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
cloud_computing_Infrastucture_as_cloud_p
Enhancing emotion recognition model for a student engagement use case through...
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Tartificialntelligence_presentation.pptx
Web App vs Mobile App What Should You Build First.pdf
Architecture types and enterprise applications.pdf
What is a Computer? Input Devices /output devices
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
Module 1.ppt Iot fundamentals and Architecture
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Group 1 Presentation -Planning and Decision Making .pptx
O2C Customer Invoices to Receipt V15A.pptx
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
A contest of sentiment analysis: k-nearest neighbor versus neural network

Native Payment - Part 3.pdf

  • 1. Native Payment - Part III
  • 2. Before We Begin ✦ Send a build with include source and open the source in the native IDE then do the implementation there, once done copy the code back to the native directory ✦ Be aware of threads. Go into the native thread and don’t forget to go back to the EDT in the callback! © Codename One 2017 all rights reserved
  • 3. final Activity act = AndroidNativeUtil.getActivity(); act.runOnUiThread(new Runnable() { public void run() { DropInRequest dropInRequest = new DropInRequest() .clientToken(param); AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act), new IntentResultListener() { public void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT); BraintreePaymentCallback.onPurchaseSuccess( result.getPaymentMethodNonce().getNonce()); } else if (resultCode == Activity.RESULT_CANCELED) { BraintreePaymentCallback.onPurchaseCancel(); } else { Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR); BraintreePaymentCallback.onPurchaseFail(error.toString()); Log.e(error); Log.sendLog(); } } }); } }); Android
  • 4. final Activity act = AndroidNativeUtil.getActivity(); act.runOnUiThread(new Runnable() { public void run() { DropInRequest dropInRequest = new DropInRequest() .clientToken(param); AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act), new IntentResultListener() { public void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT); BraintreePaymentCallback.onPurchaseSuccess( result.getPaymentMethodNonce().getNonce()); } else if (resultCode == Activity.RESULT_CANCELED) { BraintreePaymentCallback.onPurchaseCancel(); } else { Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR); BraintreePaymentCallback.onPurchaseFail(error.toString()); Log.e(error); Log.sendLog(); } } }); } }); Android Activity Almost all Android Sample code assumes this==activity. In a native interface that just isn’t true which is why in most cases where this is referenced you can just do getActivity using AndroidNative Util
  • 5. final Activity act = AndroidNativeUtil.getActivity(); act.runOnUiThread(new Runnable() { public void run() { DropInRequest dropInRequest = new DropInRequest() .clientToken(param); AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act), new IntentResultListener() { public void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT); BraintreePaymentCallback.onPurchaseSuccess( result.getPaymentMethodNonce().getNonce()); } else if (resultCode == Activity.RESULT_CANCELED) { BraintreePaymentCallback.onPurchaseCancel(); } else { Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR); BraintreePaymentCallback.onPurchaseFail(error.toString()); Log.e(error); Log.sendLog(); } } }); } }); Android UI Thread Most Android sample code assumes you are on the Android equivalent of the EDT (UI thread). We are on the Codename One EDT or a Codename One thread in a native interface so it’s best to do something like this unless you need a synchronous call
  • 6. final Activity act = AndroidNativeUtil.getActivity(); act.runOnUiThread(new Runnable() { public void run() { DropInRequest dropInRequest = new DropInRequest() .clientToken(param); AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act), new IntentResultListener() { public void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT); BraintreePaymentCallback.onPurchaseSuccess( result.getPaymentMethodNonce().getNonce()); } else if (resultCode == Activity.RESULT_CANCELED) { BraintreePaymentCallback.onPurchaseCancel(); } else { Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR); BraintreePaymentCallback.onPurchaseFail(error.toString()); Log.e(error); Log.sendLog(); } } }); } }); Android startActivityForResult This is a very common method of activity but grabbing the result isn’t intuitive which is why we have this method
  • 7. final Activity act = AndroidNativeUtil.getActivity(); act.runOnUiThread(new Runnable() { public void run() { DropInRequest dropInRequest = new DropInRequest() .clientToken(param); AndroidNativeUtil.startActivityForResult(dropInRequest.getIntent(act), new IntentResultListener() { public void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT); BraintreePaymentCallback.onPurchaseSuccess( result.getPaymentMethodNonce().getNonce()); } else if (resultCode == Activity.RESULT_CANCELED) { BraintreePaymentCallback.onPurchaseCancel(); } else { Exception error = (Exception)data.getSerializableExtra(DropInActivity.EXTRA_ERROR); BraintreePaymentCallback.onPurchaseFail(error.toString()); Log.e(error); Log.sendLog(); } } }); } }); Android Callbacks & API On Android we can access the Codename One API directly since it’s all just Java…
  • 8. dispatch_async(dispatch_get_main_queue(), ^{ BTDropInRequest *request = [[BTDropInRequest alloc] init]; BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError * _Nullable error) { if (error != nil) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription])); } else if (result.cancelled) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE _ARG); } else { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET _STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce)); } [controller dismissViewControllerAnimated:YES completion:nil]; }]; [[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES completion:nil]; }); iOS
  • 9. dispatch_async(dispatch_get_main_queue(), ^{ BTDropInRequest *request = [[BTDropInRequest alloc] init]; BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError * _Nullable error) { if (error != nil) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription])); } else if (result.cancelled) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE _ARG); } else { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET _STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce)); } [controller dismissViewControllerAnimated:YES completion:nil]; }]; [[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES completion:nil]; }); iOS iOS EDT iOS is very sensitive to EDT violations. It’s really important to use it’s main queue (native EDT) for everything related to UI
  • 10. dispatch_async(dispatch_get_main_queue(), ^{ BTDropInRequest *request = [[BTDropInRequest alloc] init]; BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError * _Nullable error) { if (error != nil) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription])); } else if (result.cancelled) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE _ARG); } else { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET _STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce)); } [controller dismissViewControllerAnimated:YES completion:nil]; }]; [[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES completion:nil]; }); iOS Self Self is the Objective-C equivalent of this. In the original code self was used as it was assumed to be a Controller (commonly used iOS abstraction) when you need a controller you can use this syntax
  • 11. dispatch_async(dispatch_get_main_queue(), ^{ BTDropInRequest *request = [[BTDropInRequest alloc] init]; BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:param request:request handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError * _Nullable error) { if (error != nil) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseFail___java_lang_String(CN1_THREAD_GET_ST ATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [error localizedDescription])); } else if (result.cancelled) { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseCancel__(CN1_THREAD_GET_STATE_PASS_SINGLE _ARG); } else { com_myrestaurant_app_payment_BraintreePaymentCallback_onPurchaseSuccess___java_lang_String(CN1_THREAD_GET _STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG result.paymentMethod.nonce)); } [controller dismissViewControllerAnimated:YES completion:nil]; }]; [[CodenameOne_GLViewController instance] presentViewController:dropIn animated:YES completion:nil]; }); iOS Callbacks Callbacks to Java code are complex and have a slightly different syntax when calling to a no-args method but IDE completion should help…
  • 12. What did we learn? ✦Native interfaces aren’t trivial, but are doable when we overcome the pitfalls and use Google aggressively ✦Error logs on Android are painful and we need to develop reading skill to go thru them ✦Use native IDE’s to develop the native code and shorten the back and forth cycles