Skip to content

Commit

Permalink
Update v3 MIGRATION GUIDE.
Browse files Browse the repository at this point in the history
  • Loading branch information
sshropshire committed Apr 2, 2024
1 parent 8466f63 commit 3b8bf62
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ package com.braintreepayments.api
sealed class BrowserSwitchStartResult {

/**
* A browser switch was successfully started. This pending request should be store dnd passed to
* [BrowserSwitchClient.parseResult]
* Browser switch successfully started. Keep a reference to pending request state and pass it to
* [BrowserSwitchClient.parseResult] after a deep link back into the app has occurred.
*/
class Success(val pendingRequestState: String) : BrowserSwitchStartResult()

/**
* An error with [cause] occurred launching the browser
* Browser switch failed with an [error].
*/
class Failure(val cause: Exception) : BrowserSwitchStartResult()
class Failure(val error: Exception) : BrowserSwitchStartResult()
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void start_whenActivityIsFinishing_throwsException() {

BrowserSwitchStartResult request = sut.start(componentActivity, options);
assertTrue(request instanceof BrowserSwitchStartResult.Failure);
assertEquals(((BrowserSwitchStartResult.Failure) request).getCause().getMessage(), "Unable to start browser switch while host Activity is finishing.");
assertEquals(((BrowserSwitchStartResult.Failure) request).getError().getMessage(), "Unable to start browser switch while host Activity is finishing.");
}

@Test
Expand Down Expand Up @@ -118,7 +118,7 @@ public void start_whenNoBrowserAvailable_returnsFailure() {
.metadata(metadata);
BrowserSwitchStartResult request = sut.start(componentActivity, options);
assertTrue(request instanceof BrowserSwitchStartResult.Failure);
assertEquals(((BrowserSwitchStartResult.Failure) request).getCause().getMessage(), "Unable to start browser switch without a web browser.");
assertEquals(((BrowserSwitchStartResult.Failure) request).getError().getMessage(), "Unable to start browser switch without a web browser.");
}

@Test
Expand All @@ -136,7 +136,7 @@ public void start_whenRequestCodeIsIntegerMinValue_returnsFailure() {
.metadata(metadata);
BrowserSwitchStartResult request = sut.start(componentActivity, options);
assertTrue(request instanceof BrowserSwitchStartResult.Failure);
assertEquals(((BrowserSwitchStartResult.Failure) request).getCause().getMessage(), "Request code cannot be Integer.MIN_VALUE");
assertEquals(((BrowserSwitchStartResult.Failure) request).getError().getMessage(), "Request code cannot be Integer.MIN_VALUE");
}

@Test
Expand All @@ -158,7 +158,7 @@ public void start_whenDeviceIsNotConfiguredForDeepLinking_returnsFailure() {
assertEquals("The return url scheme was not set up, incorrectly set up, or more than one " +
"Activity on this device defines the same url scheme in it's Android Manifest. " +
"See https://github.com/braintree/browser-switch-android for more information on " +
"setting up a return url scheme.", ((BrowserSwitchStartResult.Failure) request).getCause().getMessage());
"setting up a return url scheme.", ((BrowserSwitchStartResult.Failure) request).getError().getMessage());
}

@Test
Expand All @@ -176,7 +176,7 @@ public void start_whenNoReturnUrlSchemeSet_throwsFailure() {
.metadata(metadata);
BrowserSwitchStartResult request = sut.start(componentActivity, options);
assertTrue(request instanceof BrowserSwitchStartResult.Failure);
assertEquals("A returnUrlScheme is required.", ((BrowserSwitchStartResult.Failure) request).getCause().getMessage());
assertEquals("A returnUrlScheme is required.", ((BrowserSwitchStartResult.Failure) request).getError().getMessage());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@ import java.lang.Exception
class ComposeActivity : ComponentActivity() {

private val viewModel by viewModels<BrowserSwitchViewModel>()

private lateinit var browserSwitchClient: BrowserSwitchClient
private val browserSwitchClient = BrowserSwitchClient()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
browserSwitchClient = BrowserSwitchClient()

setContent {
Column(modifier = Modifier.padding(10.dp)) {
BrowserSwitchButton {
Expand Down Expand Up @@ -72,12 +69,12 @@ class ComposeActivity : ComponentActivity() {
.url(url)
.launchAsNewTask(false)
.returnUrlScheme(RETURN_URL_SCHEME)
when (val pendingRequest = browserSwitchClient.start(this, browserSwitchOptions)) {
when (val result = browserSwitchClient.start(this, browserSwitchOptions)) {
is BrowserSwitchStartResult.Success ->
PendingRequestStore.put(this, pendingRequest.pendingRequestState)
PendingRequestStore.put(this, result.pendingRequestState)

is BrowserSwitchStartResult.Failure -> viewModel.browserSwitchError =
pendingRequest.cause
result.error
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void startBrowserSwitch(BrowserSwitchOptions options) throws BrowserSwitc
((BrowserSwitchStartResult.Success) pendingRequest).getPendingRequestState();
PendingRequestStore.put(this, pendingRequestState);
} else if (pendingRequest instanceof BrowserSwitchStartResult.Failure) {
Objects.requireNonNull(getDemoFragment()).onBrowserSwitchError(((BrowserSwitchStartResult.Failure) pendingRequest).getCause());
Objects.requireNonNull(getDemoFragment()).onBrowserSwitchError(((BrowserSwitchStartResult.Failure) pendingRequest).getError());
}
}

Expand Down
42 changes: 33 additions & 9 deletions v3_MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ Then, add an `intent-filter` in the `AndroidManifest.xml` to your deep link dest
class MyActivity : ComponentActivity() {

val browserSwitchClient: BrowserSwitchClient = BrowserSwitchClient()
val pendingRequestState: String? = null

override fun onResume() {
super.onResume()
handleReturnToAppFromBrowser(intent)
}

Expand All @@ -54,25 +56,33 @@ class MyActivity : ComponentActivity() {
url = "https://example.com"
returnUrlScheme = "my-custom-url-scheme"
}
when (val pendingRequest = browserSwitchClient.start(this, browserSwitchOptions)) {
when (val result = browserSwitchClient.start(this, browserSwitchOptions)) {
is BrowserSwitchPendingRequest.Started -> {
// store pending request
pendingRequestState = result.pendingRequestState
}
is BrowserSwitchPendingRequest.Failure -> {
// browser was unable to be launched, handle failure
Log.d("MyActivity", result.error)
}
}
}

fun handleReturnToAppFromBrowser(intent: Intent) {
// fetch stored pending request
fetchPendingRequestFromPersistentStorage()?.let { startedRequest ->
when (val browserSwitchResult = browserSwitchClient.parseResult(startedRequest, intent)) {
is BrowserSwitchResult.Success -> {
if (pendingRequestState != null) {
when (val result = browserSwitchClient.parseResult(intent, pendingRequestState)) {
is BrowserSwitchParseResult.Success -> {
// handle successful browser switch result
// clear stored pending request
// drop reference to pending request
pendingRequestState = null
}
is BrowserSwitchResult.NoResult -> {
is BrowserSwitchParseResult.Failure -> {
// browser switch parsing failed
Log.d("MyActivity", result.error)
// drop reference to pending request
pendingRequestState = null
}
is BrowserSwitchParseResult.NoResult -> {
// user did not complete browser switch
// allow user to complete browser switch, or clear stored pending request
}
Expand All @@ -89,14 +99,28 @@ If your deep link destination activity is configured in the `AndroidManifest.xml
```kotlin
class MySingleTopActivity : ComponentActivity() {

val pendingRequestState: String? = null
val browserSwitchClient: BrowserSwitchClient = BrowserSwitchClient()

override fun onCreate() {
super.onCreate()
/**
* TODO: initialize pendingRequestState from your app's preferred persistence store
* e.g. shared prefs, data store or saved instance state
*/
pendingRequestState = ...
}

override fun onResume() {
// do nothing
super.onResume()

// handle browser switch when deep link triggers a cold start of the app
handleReturnToAppFromBrowser(intent, pendingRequestState)
}

override fun onNewIntent(newIntent: Intent) {
handleReturnToAppFromBrowser(newIntent)
// handle browser switch when deep link brings already running singleTop activity to the foreground
handleReturnToAppFromBrowser(newIntent, pendingRequestState)
}
}
```

0 comments on commit 3b8bf62

Please sign in to comment.