Reputation: 614
I have a Flutter application which use receive_sharing_intent package, and as requested by the plugin, I've created a Share Extension.
My app and the extension build and work correctly, but when I archive and distribute my app (App Store Connect), at the end of the uploading I have the following error messages:
ERROR ITMS-90057: "The bundle 'Payload/Runner.app/PlugIns/ShareExtension.appex' is missing plist key. The Info.plist is missing the required key: CFBundleShortVersionString."
ERROR ITMS-90056: "This bundle 'Payload/Runner.app/PlugIns/ShareExtension.appex' is invalid. The Info.plist is missing the required key: CFBundleVersion."
ERROR ITMS-90360: "Missing Info.plist value. A value for the key 'CFBundleVersion' in bundle Payload/Runner.app/PlugIns/ShareExtension.appex is required."
ERROR ITMS-90360: "Missing Info.plist value. A value for the key 'CFBundleShortVersionString' in bundle Payload/Runner.app/PlugIns/ShareExtension.appex is required."
But in my ios/ShareExtension/Info.plist
file I have:
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
I also tried with:
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
which remove the error for CFBundleVersion
but CFBundleShortVersionString
is still invalid.
By explicitly setting my app version and build number in the extension plist the upload succeed.
But is there a way to use FLUTTER_BUILD_NAME
and FLUTTER_BUILD_NUMBER
variables in the extension plist?
NOTE:
I'm using Xcode 11.6
Upvotes: 4
Views: 1647
Reputation: 951
I had the same problem when app version had no version code. With version like 1.0.0 ios app had missing plist key error. Try to add version code like 1.0.0+0
Upvotes: 0
Reputation: 758
Sharing my C program per @Aidan David request, but:
ZSH script:
./plist_replace_value ./NotificationService/Info.plist CFBundleVersion `grep ^version: ../pubspec.yaml | awk -F'[\+ ]' '{print $3}'`
./plist_replace_value ./NotificationService/Info.plist CFBundleShortVersionString `grep ^version: ../pubspec.yaml | awk -F'[\+ ]' '{print $2}'`
./plist_replace_value ./Share\ Extension/Info.plist CFBundleVersion `grep ^version: ../pubspec.yaml | awk -F'[\+ ]' '{print $3}'`
./plist_replace_value ./Share\ Extension/Info.plist CFBundleShortVersionString `grep ^version: ../pubspec.yaml | awk -F'[\+ ]' '{print $2}'`
C Program, plist_replace_value.c:
#include <string.h>
#include <stdio.h>
#define MAX_LINE 256
void print_usage(char *programName)
{
printf("\nUsage:\n%s <plist file> <key> <value>\n", programName);
}
int main(int argc, char *argv[])
{
FILE *plist_file, *output_file;
int replaced = 0;
char line[MAX_LINE];
printf("Plist key-value parser. Supports replacing values.\n");
fflush(stdout);
if (argc < 4)
{
fprintf(stderr, "Insufficient number of parameters.");
print_usage(argv[0]);
return 1;
}
plist_file = fopen(argv[1], "r+");
if (plist_file == NULL)
{
fprintf(stderr, "Unable to open %s, aborting...\n", argv[1]);
return 1;
}
output_file = fopen("temp.plist", "w");
if (output_file == NULL)
{
fprintf(stderr, "Unable to create temporary file, aborting...\n");
return 1;
}
fgets(line, MAX_LINE, plist_file);
while (!feof(plist_file) && !replaced)
{
fprintf(output_file, "%s", line);
if (strstr(line, argv[2]) != NULL)
{
fprintf(output_file, "\t<string>%s</string>\n", argv[3]);
// Skip the next output line
fgets(line, MAX_LINE, plist_file);
}
fgets(line, MAX_LINE, plist_file);
}
fclose(output_file);
fclose(plist_file);
remove(argv[1]);
rename("temp.plist", argv[1]);
return 0;
}
Upvotes: 0