|
| 1 | +# |
| 2 | +# Reference documentations |
| 3 | +# https://github.com/firebase/flutterfire/blob/master/packages/firebase_crashlytics/firebase_crashlytics/ios/crashlytics_add_upload_symbols |
| 4 | +# https://github.com/MagicalWater/Base-APP-Env/blob/master/fastlane/actions/xcode_parse.rb |
| 5 | +# |
| 6 | + |
| 7 | +require 'xcodeproj' |
| 8 | +require 'plist' |
| 9 | +require 'optparse' |
| 10 | +require 'uri' |
| 11 | + |
| 12 | +# Dictionary to hold command line arguments |
| 13 | +options_dict = {} |
| 14 | + |
| 15 | +# Parse command line arguments into options_dict |
| 16 | +OptionParser.new do |options| |
| 17 | + options.banner = "Setup the Wechat to an Xcode target." |
| 18 | + |
| 19 | + options.on("-p", "--projectDirectory=DIRECTORY", String, "Directory of the Xcode project") do |dir| |
| 20 | + options_dict[:project_dir] = dir |
| 21 | + end |
| 22 | + |
| 23 | + options.on("-n", "--projectName=NAME", String, "Name of the Xcode project (ex: Runner.xcodeproj)") do |name| |
| 24 | + options_dict[:project_name] = name |
| 25 | + end |
| 26 | + |
| 27 | + options.on("-i", "--ignoreSecurity", "Ignore modifying NSAppTransportSecurity") do |opts| |
| 28 | + options_dict[:ignore_security] = true |
| 29 | + end |
| 30 | + |
| 31 | + options.on("-a", "--appId=APPID", String, "App ID for Wechat") do |opts| |
| 32 | + options_dict[:app_id] = opts |
| 33 | + end |
| 34 | + |
| 35 | + options.on("-u", "--universalLink=UNIVERSALLINK", String, "Universal Link for Wechat") do |opts| |
| 36 | + options_dict[:universal_link] = opts |
| 37 | + end |
| 38 | +end.parse! |
| 39 | + |
| 40 | +# Minimum required arguments are a project directory and project name |
| 41 | +unless (options_dict[:project_dir] and options_dict[:project_name]) |
| 42 | + abort("Must provide a project directory and project name.\n") |
| 43 | +end |
| 44 | + |
| 45 | +# Path to the Xcode project to modify |
| 46 | +project_path = File.join(options_dict[:project_dir], options_dict[:project_name]) |
| 47 | + |
| 48 | +unless (File.exist?(project_path)) |
| 49 | + abort("Project at #{project_path} does not exist. Please check paths manually.\n"); |
| 50 | +end |
| 51 | + |
| 52 | +# Actually open and modify the project |
| 53 | +project = Xcodeproj::Project.open(project_path) |
| 54 | +project.targets.each do |target| |
| 55 | + if target.name == "Runner" |
| 56 | + app_id = options_dict[:app_id] |
| 57 | + |
| 58 | + sectionObject = {} |
| 59 | + project.objects.each do |object| |
| 60 | + if object.uuid == target.uuid |
| 61 | + sectionObject = object |
| 62 | + break |
| 63 | + end |
| 64 | + end |
| 65 | + sectionObject.build_configurations.each do |config| |
| 66 | + infoplist = config.build_settings["INFOPLIST_FILE"] |
| 67 | + if !infoplist |
| 68 | + abort("INFOPLIST_FILE is not exist\n") |
| 69 | + end |
| 70 | + infoplistFile = File.join(options_dict[:project_dir], infoplist) |
| 71 | + if !File.exist?(infoplistFile) |
| 72 | + abort("#{infoplist} is not exist\n") |
| 73 | + end |
| 74 | + result = Plist.parse_xml(infoplistFile, marshal: false) |
| 75 | + if !result |
| 76 | + result = {} |
| 77 | + end |
| 78 | + urlTypes = result["CFBundleURLTypes"] |
| 79 | + if !urlTypes |
| 80 | + urlTypes = [] |
| 81 | + result["CFBundleURLTypes"] = urlTypes |
| 82 | + end |
| 83 | + isUrlTypeExist = urlTypes.any? { |urlType| urlType["CFBundleURLSchemes"] && (urlType["CFBundleURLSchemes"].include? app_id) } |
| 84 | + if !app_id.nil? && !app_id.empty? && !isUrlTypeExist |
| 85 | + print("writing app id\n ") |
| 86 | + urlTypes << { |
| 87 | + "CFBundleTypeRole": "Editor", |
| 88 | + "CFBundleURLName": "douyin", |
| 89 | + "CFBundleURLSchemes": [ app_id ] |
| 90 | + } |
| 91 | + File.write(infoplistFile, Plist::Emit.dump(result)) |
| 92 | + end |
| 93 | + |
| 94 | + queriesSchemes = result["LSApplicationQueriesSchemes"] |
| 95 | + if !queriesSchemes |
| 96 | + queriesSchemes = [] |
| 97 | + result["LSApplicationQueriesSchemes"] = queriesSchemes |
| 98 | + end |
| 99 | + douYinQueriesSchemes = ["douyinopensdk", "douyinliteopensdk", "douyinsharesdk", "snssdk1128"] |
| 100 | + if douYinQueriesSchemes.any? { |queriesScheme| !(queriesSchemes.include? queriesScheme) } |
| 101 | + douYinQueriesSchemes.each do |queriesScheme| |
| 102 | + if !(queriesSchemes.include? queriesScheme) |
| 103 | + queriesSchemes << queriesScheme |
| 104 | + end |
| 105 | + end |
| 106 | + File.write(infoplistFile, Plist::Emit.dump(result)) |
| 107 | + end |
| 108 | + if !options_dict[:ignore_security] |
| 109 | + security = result["NSAppTransportSecurity"] |
| 110 | + if !security |
| 111 | + security = {} |
| 112 | + result["NSAppTransportSecurity"] = security |
| 113 | + end |
| 114 | + if security["NSAllowsArbitraryLoads"] != true |
| 115 | + security["NSAllowsArbitraryLoads"] = true |
| 116 | + File.write(infoplistFile, Plist::Emit.dump(result)) |
| 117 | + end |
| 118 | + if security["NSAllowsArbitraryLoadsInWebContent"] != true |
| 119 | + security["NSAllowsArbitraryLoadsInWebContent"] = true |
| 120 | + File.write(infoplistFile, Plist::Emit.dump(result)) |
| 121 | + end |
| 122 | + end |
| 123 | + end |
| 124 | + sectionObject.build_configurations.each do |config| |
| 125 | + codeSignEntitlements = config.build_settings["CODE_SIGN_ENTITLEMENTS"] |
| 126 | + if !codeSignEntitlements |
| 127 | + codeSignEntitlements = "Runner/Runner.entitlements" |
| 128 | + config.build_settings["CODE_SIGN_ENTITLEMENTS"] = codeSignEntitlements |
| 129 | + project.save() |
| 130 | + end |
| 131 | + codeSignEntitlementsFile = File.join(options_dict[:project_dir], codeSignEntitlements) |
| 132 | + if !File.exist?(codeSignEntitlementsFile) |
| 133 | + content = Plist::Emit.dump({}) |
| 134 | + File.write(codeSignEntitlementsFile, content) |
| 135 | + end |
| 136 | + runnerTargetMainGroup = project.main_group.find_subpath('Runner', false) |
| 137 | + isRefExist = runnerTargetMainGroup.files.any? { |file| file.path.include? File.basename(codeSignEntitlementsFile) } |
| 138 | + if !isRefExist |
| 139 | + runnerTargetMainGroup.new_reference(File.basename(codeSignEntitlementsFile)) |
| 140 | + project.save() |
| 141 | + end |
| 142 | + result = Plist.parse_xml(codeSignEntitlementsFile, marshal: false) |
| 143 | + if !result |
| 144 | + result = {} |
| 145 | + end |
| 146 | + domains = result["com.apple.developer.associated-domains"] |
| 147 | + if !domains |
| 148 | + domains = [] |
| 149 | + result["com.apple.developer.associated-domains"] = domains |
| 150 | + end |
| 151 | +# isApplinksExist = domains.include? applinks |
| 152 | +# if !isApplinksExist |
| 153 | +# domains << applinks |
| 154 | +# File.write(codeSignEntitlementsFile, Plist::Emit.dump(result)) |
| 155 | +# end |
| 156 | + end |
| 157 | + end |
| 158 | +end |
0 commit comments