From 048614c60e4a7e3308448e2ab8395c9fc64427cf Mon Sep 17 00:00:00 2001 From: inkeliz Date: Thu, 19 Dec 2024 00:30:56 +0000 Subject: [PATCH] gogio: [iOS] fix compatibility with Apple Connect and iPad requirement This pach fixes a total of 6 issues caused by gogio, when uploading .ipa to Apple Connect/Apple Store. 1. Asset validation failed (90474), caused by not set "UIInterfaceOrientationPortraitUpside" in plist. 2. Asset validation failed (90482), the executable contains bitcode. Now, gogio will use "bitcode_strip" to remove such bitcode. 3. Asset validation failed (90060), the version can only have three non-negative numbers. Using values from semVer is invalid (such as 1.2.3.4), it must be either 1.2.3 or 1.2.34. Now, gogio uses the later one. 4. Asset validation failed (90476), supporting multitask on iPad requires UILaunchScreen. That is tricky to solve, instead gogio will NOT support multitask on iPad. 5. Asset validation failed (90208), version mismatch between plist and binary. Now, gogio will use compile flags to set the version AND will use the proper minSdk on plist. 6. Asset validation failed (90023), missing 152x152 icon for iPad. Now, gogio will create such icon. Signed-off-by: inkeliz Signed-off-by: Elias Naur --- gogio/build_info.go | 5 +++ gogio/iosbuild.go | 74 ++++++++++++++++++++++++++++++--------------- gogio/main.go | 2 +- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/gogio/build_info.go b/gogio/build_info.go index 5c17f41..4125681 100644 --- a/gogio/build_info.go +++ b/gogio/build_info.go @@ -94,6 +94,11 @@ func (s Semver) String() string { return fmt.Sprintf("%d.%d.%d.%d", s.Major, s.Minor, s.Patch, s.VersionCode) } +func (s Semver) StringCompact() string { + // Used to meet CFBundleShortVersionString format. + return fmt.Sprintf("%d.%d.%d", s.Major, s.Minor, s.Patch) +} + func parseSemver(v string) (Semver, error) { var sv Semver _, err := fmt.Sscanf(v, "%d.%d.%d.%d", &sv.Major, &sv.Minor, &sv.Patch, &sv.VersionCode) diff --git a/gogio/iosbuild.go b/gogio/iosbuild.go index 08bca1b..0f76499 100644 --- a/gogio/iosbuild.go +++ b/gogio/iosbuild.go @@ -202,6 +202,7 @@ func exeIOS(tmpDir, target, app string, bi *buildInfo) error { } cflags = append(cflags, "-fobjc-arc", + fmt.Sprintf("-miphoneos-version-min=%d.0", bi.minsdk), ) cflagsLine := strings.Join(cflags, " ") exeSlice := filepath.Join(tmpDir, "app-"+a) @@ -271,6 +272,9 @@ func iosIcons(bi *buildInfo, tmpDir, appDir, icon string) (string, error) { err := buildIcons(appIcon, icon, []iconVariant{ {path: "ios_2x.png", size: 120}, {path: "ios_3x.png", size: 180}, + {path: "ipad_1x.png", size: 76}, + {path: "ipad_2x.png", size: 152}, + {path: "ipad_4x.png", size: 228}, // The App Store icon is not allowed to contain // transparent pixels. {path: "ios_store.png", size: 1024, fill: true}, @@ -279,26 +283,44 @@ func iosIcons(bi *buildInfo, tmpDir, appDir, icon string) (string, error) { return "", err } contentJson := `{ - "images" : [ - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "ios_2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "ios_3x.png", - "scale" : "3x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "ios_store.png", - "scale" : "1x" - } - ] +"images": [ + { + "size": "60x60", + "idiom": "iphone", + "filename": "ios_2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "ios_3x.png", + "scale": "3x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "ipad_1x.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "ipad_2x.png", + "scale": "2x" + }, + { + "size": "152x152", + "idiom": "ipad", + "filename": "ipad_4x.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "ios_store.png", + "scale": "1x" + } +] }` contentFile := filepath.Join(appIcon, "Contents.json") if err := os.WriteFile(contentFile, []byte(contentJson), 0o600); err != nil { @@ -345,10 +367,10 @@ func buildInfoPlist(bi *buildInfo) string { }{ AppName: appName, AppID: bi.appID, - Version: bi.version.String(), + Version: bi.version.StringCompact(), VersionCode: bi.version.VersionCode, Platform: platform, - MinVersion: minIOSVersion, + MinVersion: bi.minsdk, SupportPlatform: supportPlatform, Schemes: bi.schemes, } @@ -382,7 +404,7 @@ func buildInfoPlist(bi *buildInfo) string { DTPlatformVersion 12.4 MinimumOSVersion - {{.MinVersion}} + {{.MinVersion}}.0 UIDeviceFamily 1 @@ -395,9 +417,12 @@ func buildInfoPlist(bi *buildInfo) string { UISupportedInterfaceOrientations UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIRequiresFullScreen + DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild @@ -410,6 +435,8 @@ func buildInfoPlist(bi *buildInfo) string { 1030 DTXcodeBuild 10G8 + UILaunchScreen + {{if .Schemes}} CFBundleURLTypes @@ -575,7 +602,6 @@ func iosCompilerFor(target, arch string, minsdk int) (string, []string, error) { return "", nil, err } cflags := []string{ - "-fembed-bitcode", "-arch", allArchs[arch].iosArch, "-isysroot", sdkPath, "-m" + platformOS + "-version-min=" + strconv.Itoa(minsdk), diff --git a/gogio/main.go b/gogio/main.go index 8ef6f89..c8dd962 100644 --- a/gogio/main.go +++ b/gogio/main.go @@ -29,7 +29,7 @@ var ( destPath = flag.String("o", "", "output file or directory.\nFor -target ios or tvos, use the .app suffix to target simulators.") appID = flag.String("appid", "", "app identifier (for -buildmode=exe)") name = flag.String("name", "", "app name (for -buildmode=exe)") - version = flag.String("version", "1.0.0.1", "semver app version (for -buildmode=exe) on the form major.minor.patch.versioncode") + version = flag.String("version", "1.0.0.1", "semver app version (for -buildmode=exe) on the form major.minor.patch.versioncode. The versioncode is not used for iOS and macOS.") printCommands = flag.Bool("x", false, "print the commands") keepWorkdir = flag.Bool("work", false, "print the name of the temporary work directory and do not delete it when exiting.") linkMode = flag.String("linkmode", "", "set the -linkmode flag of the go tool")