Extension Version Mismatch

| /

When we need to intercept the pushed information and customize the display, we need to use the extension capabilities provided by Apple. It means that our project will become a multi-target project.

At this time, we may encounter the problem of version mismatch.

When we submit to Apple for review, to be precise, when we submit the production certificate signature package, we may receive an email similar to the following:

App Store Connect

Dear Developer,

We identified one or more issues with a recent delivery for your app, “ABCD”. Your delivery was successful, but you may wish to correct the following issues in your next delivery:

CFBundleVersion Mismatch - The CFBundleVersion value ‘1’ of extension ‘abcd.app/PlugIns/pushservice.appex’ does not match the CFBundleVersion value ‘168’ of its containing iOS application ‘abcd.app’.

CFBundleShortVersionString Mismatch - The CFBundleShortVersionString value ‘1.0’ of extension ‘abcd.app/PlugIns/pushservice.appex’ does not match the CFBundleShortVersionString value ‘2.16.0’ of its containing iOS application ‘abcd.app’.

After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to App Store Connect.

Best regards,

The App Store Team

In fact, we found that even if we ignore this email and do nothing, our APP can still be approved normally, and even our extension can work normally.

But anyway, to solve this problem, or a better way to deal with it.

Simply put, the version number of the extension is inconsistent with the version number of the main APP.

The easiest way is to manually modify the relevant extension version number every time you submit.

But sometimes, the company’s common platform will help us do version number maintenance. Helped, but not all.

This gives us a problem, and may need to anticipate possible minor version number jumps. As well as tolerating a certain level of version number inconsistency.

The problem of automatic version number synchronization may be a common problem, and it may also be encountered in Pods. See this article Preprocessor Macros in Pods.

Of course, we still expect the most perfect solution to this problem.

The common idea is to execute a script to synchronize the version number at the right time in Build Phases.

Here are a few important notes:

  1. To be processed at the compile time of sub-targets (ie extension). Because of the order of compilation dependencies, it is determined that the compilation and signature of the sub-targets are executed first, and then the main target is executed. Because the main target depends on the child targets.
    When the main target is compiled, the sub-targets have been compiled and signed, especially the signature. If you modify the info.plist file in the sub-targets at this time, it will cause problems such as inconsistent signatures.
    The debug local debugging seems to be fine, but there will be problems with the actual signature packaging, because the debug mode does not strictly verify the signature, so the problem is not exposed.

  2. When modifying info.plist, it is best to use the PlistBuddy tool provided by the system to modify it, rather than using the text editing tool directly. On the one hand, info.plist may be binary or xml, and the other is convenient for text editing tools that are more prone to errors.

In practice, the specific approach is as follows:

In the Build Phases of the sub-targets (extension), before Compile Sources, add a Phase to synchronize the version number.

The code can be written as follows:

# abcd is the Main Project Dir

# main info.plist
bundleShortVer=`/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "${mainInfoPlist}"`
buildNum=`/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "${mainInfoPlist}"`
# logger
# echo "push-sync-bundle-ver-${bundleShortVer}"
# echo "push-sync-build-num-${buildNum}"
# Replace sub info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $bundleShortVer" "${pushInfoPlist}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNum" "${pushInfoPlist}"

For the location and general writing of the specific configuration in the project project, you can refer to the following two example pictures.