AppStoreConnect version coding for test and release - ios

I have an app I developed in Xcode for Apple devices, and I have the following question I'm not sure how to deal with.
I have a server side to my app, and for testing I use a development URL, which has dummy data. When releasing, I connect to the live URL, which is connected to the live data.
Now, sometimes I make a build with the development URL that I want to put into TestFlight for the users to test, but I want to make sure that its clear on the app store connect, that this is a build connected to the development URL. I don't want in the future to publish this build by mistake. So I tried in the version to put 2.0.2-DEV, but when sending to the App Store, Xcode gave me an error:
The provided entity includes a relationship with an invalid value.
And this is because the version code has to be number.number.numnber without any text.
I also tried to do it, that the builds connected to the development URL, will be coded from 9.0.0, etc. However, once I did this, when I released new versions with the live URL, for example. 2.0.1, the users were not notified, since this number is before 9.0.0
I hope it’s clear what I am trying to say,
So how can I label a build to be using the dev development URL, so it will be clear on the app store connect that it’s not a live build?

You can not release a development and production to TestFlight. TestFlight is only for production.
But you can:
Always release the app using Phased release, so you can halt the rollout quickly if you released the wrong version.
You can use only odd numbers for development and even numbers for production

Related

How to have multiple versions of app in TestFlight?

I've just published an app on Apple's store and I'm wondering about having multiple versions of the same app for testing on TestFlight. Of course dev doesn't stop when publishing... from now on I'll have to update the app store version (v1.0.0) with bug fixes (v1.0.1, v1.0.2, ...) and before doing so I'd like to check them in test flight to ensure the fix was appropriate.
My problem is that I'm already starting to develop the next version with further functionalities of the app which will become v1.1
So ideally I'd like to have my app available both for my bug fixes, for instance v1.0.2 and also my next version v1.1.0 (this will include all bug fixes made to the store version and also many new features, refactors, redesign, etc)
I know that if I build and upload to the apple store connect a build with v1.1.0 (next version) I won't be able to upload one for a built with a bug fix on the current app store version (v1.0.2) since this version would be lower than the one I uploaded (next version)
Is there a way to accomplish this? I've read this article https://savvyapps.com/blog/using-testflight-to-distribute-multiple-versions-ios-app which solution is to create extra applications in iTunes with different app ids and bind them to different certificates. But what will happen when the next release is ready to be in the store? I would have to release it and then disable the previous one? How may this affect my users? Will they have to re-install a new app rather than updating it?
I really need to start testing and checking the next release of my app in TestFlight and also support the current one with updates if something pops up. Thanks in advance!
I am able to upload multiple versions of the app to TestFlight. Each upload requires a higher version/build number, but you can switch the TestFlight test version between them as need be for testing.
Once I submit a particular build for release, however, I seem to lose the TestFlight access to the old builds.
In short, you can have many builds available in TestFlight, but once you submit the app for release, you have to start over making builds for TestFlight.
You keep talking about numbers like v1.0.1. That looks like a public-facing version string, with a major, minor, and patch number.
But that is not what TestFlight cares about. Well, it cares to some extent. But all TestFlight really cares about is that every new build you upload has a new build number. This is just an integer which you simply increment every time you submit a new build.
So you could have v1.0.1(23) on the App Store, and then on TestFlight you could upload v1.0.2(24) which starts moving forward toward version 1.0.2, but also upload v1.0.2(25) which is actually an attempt at a prospective version 1.1. TestFlight doesn't know or care what these different builds signify. They can all exist simultaneously on TestFlight. Keeping them all straight and on their individual trajectories is up to you.

iOS App HTTP insecure call working on local tests but fails after archiving

Two years ago I developed an iOS app which makes HTTP requests instead of HTTPS ones. I had to add the Allow Arbitrary Loads value in my info.plist for this to work. The app was submitted and uploaded to the App Store and was working well until these days.
Recently, I made some improvements in other sections of the app and submitted a new version. I tested it in simulator and in an iPad an everything was working well until I archived it and generated the IPA file in Xcode. Testing this file in the same device, when I use a function that calls a HTTP request, the request gets stuck and never ends.
As when testing from Xcode everything goes well, I can´t see any error. Any idea? Has something changed recently in relation whit this kind of calls?
Update
Found that Archiving uses Release config and my tests were made in Debug, I started playing with the different build settings and detected that enabling the "Testability" option in Build Options makes everything work again. The Xcode description for this option is:
When this setting is activated, the product will be built with options appropriate for running automated tests, such as making private interfaces accessible to the tests. This may result in tests running slower than they would without testability enabled.
I don't understand the relation between this option and the HTTP requests... Can I upload the app with this option enabled?
As no other answers are being posted, if someone comes here looking for one: I had to enable "Testability" option in Build Options for Release. For me it looks like a bug and maybe this could be corrected in future versions.

How to manage app server changes when an iOS app is in review?

I want to know how others are managing their back end API's during the time when their iOS app is under review.
We are constantly updating/adding new API endpoints every release. The major problem we're encountering is when we have to make DB schema changes. We don't want to promote our backend changes to our production server until after the app has been approved by Apple (which may take up to 4+ days).
Currently, we set our iOS app to manual release and flip between 2 production servers. So app v1.0 in the app store will point to our prod1 server and app v2.0 in review will point to our prod2 server. When Apple approves v2.0, we copy our prod1 database to prod2, run all the migrations and then release v2.0. Once we've promoted our changes to prod2, we'll update a config setting on prod1 that will send a response back to app v1.0 providing a link to the app store to download app v2.0.
It feels like there are better ways to solve this problem. Interested to see how others have approached this issue.
We've successfully used the iOS app version (passed as part of the headers) in the REST calls to support multiple app versions on the same server(s). Seeing as you often have to support multiple older versions of the iOS client anyway this seems to be the simplest approach.

How to detect Apple's reviewers in iOS app?

I have an interesting issue with submitting an update for my iOS app. I have 2 API versions: production and staging. The TestFlight builds use the staging server, and the App Store builds use production via this check:
if ([[NSBundle mainBundle] pathForResource:#"embedded" ofType:#"mobileprovision"]) {
// TestFlight, use staging API
} else {
// App Store, use production API
}
This works great. We get to test the next version of the app with the next version of the API, while keeping the released version working with the production API.
The problem is that when we submit the app to Apple for review, their reviewers now have the new code that needs the new API, but the above check points them to the production API. This caused a crash and thus we got rejected.
I know that we should do proper API versioning so we could have the old and new API running in production at the same time, but sadly we're not at that stage yet. We mistakenly figured that the Apple reviewers would take the first code path (using the staging server), and we would manually release the app after it got approved and time that with deploying the new API to production and thus everything would work out just fine.
So, finally the question. Is there any way in code to detect if the app is run by Apple's reviewers, have it use the staging server? Or are we screwed and need to get the new API into production (and thus breaking the app that's currently in the App Store)?
I don't believe that you will find a reliable way of detecting the reviewer activity.
Is it possible to add a new "API" on your server specifically for your new app where it can post its version and get an answer back as to whether it is released or not (and therefore which server it should talk to subsequently)?
Once the app is approved then you can change the answer from this new API. You could even store a "production" answer in NSUserDefaults so that the app no longer checks each time once it "knows" it is in production - presumably you would never revert to staging.

iOS app works in Debug/Release/Adhoc but not when downloaded from App Store

I recently updated an app that was previously published to iOS 7.
The app works fine in every case, except when it is downloaded from the App Store. Even when published to TestFlight and installed from there.
The code block where it is not working is at a point where it retrieves a file from a remote HTTP server.
I have tried to sniff the network by having it connect to WiFi through my Mac and running a packet sniffer, but it doesn't even seem to make the HTTP GET request.
Obviously this is very hard to debug because it has to go through the store process.
Is there a way to take the binary package that I would upload to the store, and sideload it onto a device for debugging?
Start with comparing your build settings for "Release" and "AppStore".
There might be a difference.
Another source of error might be that you have something on your device in (in NSUserSettings for example) that does not exist on devices where you deploy the app store build to.
Third option I can think of is an #if somewhere in your code, like
#if RELEASE || DEBUG
SuperImportantCallToMakeItWork();
#endif
You need to have exact same test conditions for the release and the app store build. The same device, if necessary a fresh reinstall.
The store processing does not change your binary. It is just a release version (if you configured everything correctly).

Resources