Programming with AI
ENRU
12.2

Android and iOS

versions, signing, permissions, identifier

What it is

Besides its code, a mobile application has a passport: who released it, which version it is, what it is allowed to do and what the system calls it. Those four things live not in the code but in the settings of the platform folders — and they are exactly why a build that ran beautifully on your own phone isn't accepted by the store.

An AI helps less here than with code: the requirements change every year while the training data stays the same. The concepts themselves, though, don't change for decades — and those are the ones worth knowing.

What it looks like in code

1. The version is two different numbers

version: 1.2.0+34

One line in pubspec.yaml, and the build turns it into two values:

PartAndroidiOSWho sees it
1.2.0versionNameVersionthe user, in the store
34versionCodeBuildthe store only

The first is for people, shown in the update's description. The second is for the store, and it has to grow with every upload. If it didn't, the upload is rejected with a message that this version already exists.

That is the most frequent and most foolish waste of time when shipping: the build takes twenty minutes and the rejection comes because of a number nobody incremented.

2. The identifier is forever

measured
Android:  com.lunario.weather      (applicationId)
iOS:      com.lunario.weather      (bundle identifier)

This is the application's internal name in the system and in the store. There is one rule and it is hard: after the first release it cannot be changed. You can only publish a different application and ask users to reinstall — losing every review, rating and install.

Project templates put com.example.<name> here. You can't publish with com.example: the stores don't accept such identifiers. Change it before the first release, and preferably on day one.

3. Permissions are declared in two places, differently

Android — a list in the manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>

iOS — not a list but explanations for the user:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Needed to show the weather in your city.</string>

The difference is fundamental. On Android you declare what the application needs. On iOS you are obliged to write why — in text the user will see in the system dialog. No text and the application won't pass review, and on a device it will crash at the moment of the request.

And one more thing people often misunderstand: a declaration in the manifest isn't a permission. The permission is granted by the user, while the application is running, and they can refuse (article 11.5). The declaration only gives you the right to ask.

4. Signing

The artifact that goes to the store is signed with a cryptographic key. The signature answers one question: is this an update to the same application, or a different one?

PlatformWhat signs itWhere it is kept
Androida key in a keystore filewith you, not in the repository
iOSa developer certificate and a profilein your Apple account

There is one thing you need to know about the Android key, and it is unpleasant: lose the key and you can't release an update. Ever. The application stays in the store and cannot be updated — only republished under a new identifier. The store's signing service partly saves the situation, but it has to be switched on in advance, before the first release.

Hence two rules:

  • The key and its passwords do not go into the repository. The keystore file, the passwords and the paths to them go into a file that is in .gitignore. That is exactly the conversation about .env from article 5.7, only with higher stakes.
  • A backup of the key in two places, and neither of them your laptop.

The debug signature the tools use for development builds is no good for the store. The sign of trouble: the artifact is called app-debug.apk, or the build log shows signingConfig debug.

What else will cut users off

measured
minSdk 26      ← below this Android version the app won't install

The minimum system version is a quiet decision with loud consequences. Raised it to make a library work and you cut off some of your users. That is a normal trade, but it has to be a conscious one: an AI raises the minimum version in passing, with one line in the settings, and doesn't mention it in the explanation.

What to tell the AI

The key technique for this article is to demand an account of the consequences, not edits. Platform settings change rarely and cost a lot.

Prompt
Propose what to change to make this library work.
For each edit in android/ and ios/, write separately what it
changes for the user: minimum system version, new
permissions, app size. Flag edits touching minSdk
explicitly.
Prompt
Here is my application's permission list: <list>.
The application only does <description>.
Which permissions are unnecessary? For each one that is
needed, write the iOS explanation text — one sentence.

That second request solves two problems at once: it removes the surplus permissions that get releases rejected, and it writes the very explanation texts people forget.

Prompt
I'm preparing an update. What has to be raised in the
version, and where exactly is it recorded in the project?
Show the line before and after.
Prompt
Check whether signing files and passwords have got into the
repository: keys, keystores, profiles, properties files.
A list of what you find and the lines for .gitignore.

What to look for

Permissions "just in case". An application with a list of cities has acquired the camera and contacts. An AI adds permissions when a library could theoretically use them. Stores reject you for that, and users uninstall.

No explanation text for iOS. The permission is declared, the explanation isn't: rejected at review.

The version wasn't raised. Upload rejected, twenty minutes of building wasted.

The identifier is still com.example. The template wasn't edited.

A debug signature. app-debug.apk instead of a signed artifact.

Signing files in the repository. The keystore, passwords, profiles — all of it goes into the git history, and from there it isn't simply removed.

minSdk raised with no explanation. One line, and some of your users can no longer install the application.

A permission declared but refusal unhandled. The most frequent code mistake on this subject — the same one as in article 11.5.

Cheat sheet

  • 1.2.0+34: the first is for people, the second is for the store and has to grow.

  • The application identifier can't be changed after release — decide at once.

  • Android declares permissions, iOS demands an explanation — in text.

  • A manifest declaration ≠ a permission: the user grants it and can refuse.

  • Lose the signing key and there are no more updates. A copy in two places.

  • Keys and passwords go in .gitignore, not in the repository.

  • minSdk is a decision about who won't be able to install the app.

  • Ask an AI not for a settings edit but for an edit with its price to the user.