Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safer check of .appStore vs .testFlight build, and enables TESTFLIGHT deployment #76

Merged
merged 2 commits into from
Jan 30, 2024

Conversation

johnqh
Copy link
Contributor

@johnqh johnqh commented Jan 30, 2024

@mike-dydx This is what I meant as we discussed.

It would require a TESTFLIGHT deployment in the env.json, which should contain deployer's mainnet and our testnet environments.

@johnqh johnqh requested a review from mike-dydx January 30, 2024 00:27
Comment on lines +158 to +159
case .testFlight:
deployment = "TESTFLIGHT"
Copy link
Contributor

@mike-dydx mike-dydx Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the value/benefit of TESTFLIGHT ?

I am assuming the TESTFLIGHT deployment contains mainnet and testnet environments

If app store review build results in testFlight (we are not certain), then they will see those as the default selectable environments. App review might say "you cannot expose beta/test environments to users" and reject. I think apple might like to see that test environment access is behind special submission instructions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TESTFLIGHT deployment would have both mainnet and testnet, and default to mainnet, so unless reviewer enables debug and then switch to testnet environment, he is on mainnet.

It should be something like:

"TESTFLIGHT": {
         "environments": [
            "dydxprotocol-mainnet"
            "dydxprotocol-testnet"
         ],
         "default": "dydxprotocol-mainnet"
      },

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right. I am forgetting that the menu is hidden unless the Debug flag is enabled via QR code. I will get this updated in v4-web as well.

Copy link
Contributor Author

@johnqh johnqh Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am doing a PR on v4-web for this

Comment on lines 22 to 30
private static let isAppStore = {
if let receipt: URL = Bundle.main.appStoreReceiptURL {
var error: NSError?
if (receipt as NSURL).checkResourceIsReachableAndReturnError(&error), error == nil {
return true
}
}
return false
}()
Copy link
Contributor

@mike-dydx mike-dydx Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think my PR has the same logical outcomes, but without using the checkResourceIsReachableAndReturnError API (which is a synchronous round trip)

This method synchronously checks if the file at the provided URL is reachable. Checking reachability is appropriate when making decisions that do not require other immediate operations on the resource, such as periodic maintenance of user interface state that depends on the existence of a specific document. For example, you might remove an item from a download list if the user deletes the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only different is with app reviewer.

We don't know what receipt file URL they have. If it is "sandboxReceipt", with previous logic, they will end up in.appStore. But if we check if it is reachable (essentially check if the receipt file is present), then reviewer will end up in .testFlight.

Copy link
Contributor

@mike-dydx mike-dydx Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from my PR
if Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" is true, then outcome is .testfFlight

if Bundle.main.appStoreReceiptURL?.lastPathComponent != "sandboxReceipt" is true, then outcome is .appStore unless jailbroken or isDebug is true✅

if Bundle.main.appStoreReceiptURL?.lastPathComponent == nil is true, then outcome is .appStore unless jailbroken or isDebug is true. To be safe in the case that app review does not have an appStoreReceiptURL, this outcome should be .testFlight so this is incorrect ❌

so my PR has a potential issue depending on app review binary


for your PR
if Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" is true, then outcome is .appStore if checkResourceIsReachableAndReturnError is true (i think this might be incorrectly true? since the appStoreReceiptURL might still be reachable with checkResourceIsReachableAndReturnError) ❌

if Bundle.main.appStoreReceiptURL?.lastPathComponent != "sandboxReceipt" is true, then outcome is .appStore if checkResourceIsReachableAndReturnError is true ✅

if Bundle.main.appStoreReceiptURL?.lastPathComponent == nil is true, then outcome is .testFlight if checkResourceIsReachableAndReturnError is true ✅

so your PR has a potential issue depending on app review binary as well. This is only if the sandbox receipt url is reachable


I think we might need to combine both of ours to be 100% safe?

    public static var source: Source {
        if isJailBroken {
            return .jailBroken
        } else if isDebug {
            return .debug
        } else if isTestFlight {
            //reached if `Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"`
            return .testFlight
        } else if isAppStore {
            //reached if `Bundle.main.appStoreReceiptURL?.lastPathComponent != "sandboxReceipt"`
            return .appStore
        } else {
            //reached if `Bundle.main.appStoreReceiptURL?.lastPathComponent == nil`
            return .testFlight 
        }
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additionally, I cannot think of a scenario where Bundle.main.appStoreReceiptURL != nil && checkResourceIsReachableAndReturnError == false

so maybe we can remove the synchronous checkResourceIsReachableAndReturnError to reduce app start-up time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is checkResourceIsReachableAndReturnError, which is true if the receipt file exists. This is battle tested, in our v3 (and many apps before I used it in dYdX)
"sandboxReceipt" is undocumented and can change anytime.

Copy link
Contributor Author

@johnqh johnqh Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mike-dydx Like I said in Huddle, I think using "sandboxReceipt" should work. Worst case is that if Apple changes the receipt name (or Apple review has a different receipt name), the TestFlight/Reviewer app behaves like App Store download. If that happens, we can deal with it later. I reverted my changes back to use "sandboxReceipt" check

…it should work. No need to spend more time on it
@mike-dydx mike-dydx merged commit 12d2e50 into main Jan 30, 2024
1 of 2 checks passed
@mike-dydx mike-dydx deleted the feature/testflight branch January 30, 2024 01:49
mike-dydx pushed a commit that referenced this pull request Aug 20, 2024
mike-dydx pushed a commit that referenced this pull request Aug 21, 2024
mike-dydx pushed a commit that referenced this pull request Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants