diff --git a/QLAppBundle.xcodeproj/project.pbxproj b/QLAppBundle.xcodeproj/project.pbxproj index ffcdff9..48bc75b 100644 --- a/QLAppBundle.xcodeproj/project.pbxproj +++ b/QLAppBundle.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ 54B6FFF12EB6AA0F007397C0 /* AssetCarReader.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 54352E8A2EB6A79A0082F61D /* AssetCarReader.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 54B6FFF52EB6AA14007397C0 /* AssetCarReader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54352E8A2EB6A79A0082F61D /* AssetCarReader.framework */; }; 54B6FFF62EB6AA14007397C0 /* AssetCarReader.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 54352E8A2EB6A79A0082F61D /* AssetCarReader.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 54CCF59E2EDC9A6800D766F9 /* AndroidSdkMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CCF59D2EDC9A6800D766F9 /* AndroidSdkMap.swift */; }; 54D3A6EC2EA31B52001EF4F6 /* AppCategories.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54D3A6EB2EA31B52001EF4F6 /* AppCategories.swift */; }; 54D3A6EE2EA39CC6001EF4F6 /* AppIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54D3A6ED2EA39CC6001EF4F6 /* AppIcon.swift */; }; 54D3A6F02EA3F49F001EF4F6 /* NSBezierPath+RoundedRect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54D3A6EF2EA3F49F001EF4F6 /* NSBezierPath+RoundedRect.swift */; }; @@ -177,6 +178,7 @@ 54AE5BFB2EB3DB1000B4CFC7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54AE5BFD2EB3DB1000B4CFC7 /* ThumbnailProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailProvider.swift; sourceTree = ""; }; 54B6FFEC2EB6A847007397C0 /* AssetCarReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetCarReader.swift; sourceTree = ""; }; + 54CCF59D2EDC9A6800D766F9 /* AndroidSdkMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AndroidSdkMap.swift; sourceTree = ""; }; 54D3A6EB2EA31B52001EF4F6 /* AppCategories.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCategories.swift; sourceTree = ""; }; 54D3A6ED2EA39CC6001EF4F6 /* AppIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIcon.swift; sourceTree = ""; }; 54D3A6EF2EA3F49F001EF4F6 /* NSBezierPath+RoundedRect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSBezierPath+RoundedRect.swift"; sourceTree = ""; }; @@ -240,9 +242,10 @@ 54993B922EDBB419008B656D /* Plist+iTunesMetadata.swift */, 54993B942EDBC813008B656D /* Plist+MobileProvision.swift */, 54993B962EDC7C61008B656D /* Provisioning.swift */, - 540B77D82ED79BB2009E030C /* ApkManifest.swift */, - 54D3A6EB2EA31B52001EF4F6 /* AppCategories.swift */, 5469E11C2EA5930C00D46CE7 /* Entitlements.swift */, + 54D3A6EB2EA31B52001EF4F6 /* AppCategories.swift */, + 54CCF59D2EDC9A6800D766F9 /* AndroidSdkMap.swift */, + 540B77D82ED79BB2009E030C /* ApkManifest.swift */, 547F52DC2EB2C15D002B6D5F /* ExpirationStatus.swift */, 547F52E62EB2C41C002B6D5F /* PreviewGenerator.swift */, 547F52EC2EB2C822002B6D5F /* Preview+AppInfo.swift */, @@ -579,6 +582,7 @@ 547F52E82EB2C41C002B6D5F /* PreviewGenerator.swift in Sources */, 54993B882EDB9AA1008B656D /* Plist+Info.swift in Sources */, 547F52EB2EB2C672002B6D5F /* Preview+FileInfo.swift in Sources */, + 54CCF59E2EDC9A6800D766F9 /* AndroidSdkMap.swift in Sources */, 547F52ED2EB2C822002B6D5F /* Preview+AppInfo.swift in Sources */, 549E3BA12EBAE7D300ADFF56 /* URL+File.swift in Sources */, 547F52F42EB2CA05002B6D5F /* Preview+Entitlements.swift in Sources */, diff --git a/src/AndroidSdkMap.swift b/src/AndroidSdkMap.swift new file mode 100644 index 0000000..c30d60a --- /dev/null +++ b/src/AndroidSdkMap.swift @@ -0,0 +1,45 @@ +// see https://developer.android.com/guide/topics/manifest/uses-sdk-element#api-level-table + +let AndroidSdkMap: [Int: String] = [ + 1: "1.0", + 2: "1.1", + 3: "1.5", + 4: "1.6", + 5: "2.0", + 6: "2.0.1", + 7: "2.1.x", + 8: "2.2.x", + 9: "2.3, 2.3.1, 2.3.2", + 10: "2.3.3, 2.3.4", + 11: "3.0.x", + 12: "3.1.x", + 13: "3.2", + 14: "4.0, 4.0.1, 4.0.2", + 15: "4.0.3, 4.0.4", + 16: "4.1, 4.1.1", + 17: "4.2, 4.2.2", + 18: "4.3", + 19: "4.4", + 20: "4.4W", + 21: "5.0", + 22: "5.1", + 23: "6.0", + 24: "7.0", + 25: "7.1, 7.1.1", + 26: "8.0", + 27: "8.1", + 28: "9", + 29: "10", + 30: "11", + 31: "12", + 32: "12", + 33: "13", + 34: "14", + 35: "15", + 36: "16", + // can we assume new versions will stick to this scheme? + 37: "17", + 38: "18", + 39: "19", + 40: "20", +] diff --git a/src/ApkManifest.swift b/src/ApkManifest.swift index 9d2cf5e..49abe71 100644 --- a/src/ApkManifest.swift +++ b/src/ApkManifest.swift @@ -13,8 +13,8 @@ struct ApkManifest { var appIconData: Data? = nil var versionName: String? = nil var versionCode: String? = nil - var sdkVerMin: String? = nil - var sdkVerTarget: String? = nil + var sdkVerMin: Int? = nil + var sdkVerTarget: Int? = nil var featuresRequired: [String] = [] var featuresOptional: [String] = [] @@ -122,8 +122,8 @@ private class ApkXmlManifestParser: NSObject, XMLParserDelegate { } case "uses-sdk": if _scope == ["manifest"] { - result.sdkVerMin = attrs["android:minSdkVersion"] ?? "1" // "21" - result.sdkVerTarget = attrs["android:targetSdkVersion"] // "35" + result.sdkVerMin = Int(attrs["android:minSdkVersion"] ?? "1") // "21" + result.sdkVerTarget = Int(attrs["android:targetSdkVersion"] ?? "-1") // "35" } default: break // ignore } diff --git a/src/AppCategories.swift b/src/AppCategories.swift index e5f80b1..bcffae1 100644 --- a/src/AppCategories.swift +++ b/src/AppCategories.swift @@ -1,5 +1,3 @@ -import Foundation - /* #!/usr/bin/env python3 # download: https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres diff --git a/src/Preview+AppInfo.swift b/src/Preview+AppInfo.swift index 13656f9..bd7d234 100644 --- a/src/Preview+AppInfo.swift +++ b/src/Preview+AppInfo.swift @@ -19,7 +19,7 @@ extension PreviewGenerator { ]) } - /// Process info stored in `Info.plist` + /// Process info stored in `AndroidManifest.xml` mutating func procAppInfoAndroid(_ manifest: ApkManifest) { let featReq = manifest.featuresRequired let featOpt = manifest.featuresOptional @@ -29,8 +29,8 @@ extension PreviewGenerator { "
\(list.joined(separator: "\n"))
" } - func resolveSDK(_ sdk: String?) -> String { - sdk == nil ? "" : "\(sdk!) (Android \(ANDROID_SDK_MAP[sdk!] ?? "?"))" + func resolveSDK(_ sdk: Int?) -> String { + sdk == nil ? "" : "\(sdk!) (Android \(AndroidSdkMap[sdk!] ?? "?"))" } self.apply([ "AppInfoHidden": CLASS_VISIBLE, @@ -53,46 +53,3 @@ extension PreviewGenerator { } } -private let ANDROID_SDK_MAP: [String: String] = [ - "1": "1.0", - "2": "1.1", - "3": "1.5", - "4": "1.6", - "5": "2.0", - "6": "2.0.1", - "7": "2.1.x", - "8": "2.2.x", - "9": "2.3, 2.3.1, 2.3.2", - "10": "2.3.3, 2.3.4", - "11": "3.0.x", - "12": "3.1.x", - "13": "3.2", - "14": "4.0, 4.0.1, 4.0.2", - "15": "4.0.3, 4.0.4", - "16": "4.1, 4.1.1", - "17": "4.2, 4.2.2", - "18": "4.3", - "19": "4.4", - "20": "4.4W", - "21": "5.0", - "22": "5.1", - "23": "6.0", - "24": "7.0", - "25": "7.1, 7.1.1", - "26": "8.0", - "27": "8.1", - "28": "9", - "29": "10", - "30": "11", - "31": "12", - "32": "12", - "33": "13", - "34": "14", - "35": "15", - "36": "16", - // can we assume new versions will stick to this scheme? - "37": "17", - "38": "18", - "39": "19", - "40": "20", -]