问题
2020年5月以来,上传到iTunes Connect的ipa文件如包含UIWebView相关引用,会导致ipa包无法通过处理,构建版本不可用。
审核团队在邮件中给出的说明如下:
ITMS-90809: Deprecated API Usage – Apple will stop accepting submissions of apps that use UIWebView APIs . See https://developer.apple.com/documentation/uikit/uiwebview
for more information.
使用find
查找工程中相关API:
find . | grep -v .svn | grep "\.a" | grep -v "\.app" | xargs grep UIWebView
结果指向libiPhone-lib.a文件,该文件是Unity导出工程时生成的系统库文件,说明其中包含UIWebView引用。
解决方案
【方案一】
升级Unity版本
Unity在Unity2017.4.33版本中修复了此问题,条件允许可升级Unity版本来解决。
iOS:Fixed Deprecated API Usage warning for using UIWebView when submitting Builds to the App Store Connect.(1180664, 1182274)
【方案二】
去除libiPhone-lib.a中UIWebView的引用
-
首先,生成一个URLUtility.mm文件
#include
#import using namespace std; namespace core { template class StringStorageDefault {}; template class basic_string { public: char * str; basic_string( char* arg){ str = arg; } }; } void OpenURLInGame(core::basic_string< char,core::StringStorageDefault > const&arg){} void OpenURL(core::basic_string >const &arg){ const void *arg2 = arg.str; UIApplication *app = [UIApplication sharedApplication]; NSString *urlStr = [NSString stringWithUTF8String:(char *)arg2]; NSURL *url = [NSURL URLWithString:urlStr]; if (@available(iOS 10.0, *)) { [app openURL:url options:@{UIApplicationOpenURLOptionsSourceApplicationKey : @YES} completionHandler:nil]; } else { [app openURL:url]; } } void OpenURL(std::string const&arg){ UIApplication *app = [UIApplication sharedApplication]; NSString *urlStr = [NSString stringWithUTF8String:arg.c_str()]; NSURL *url = [NSURL URLWithString:urlStr]; if (@available(iOS 10.0, *)) { [app openURL:url options:@{UIApplicationOpenURLOptionsSourceApplicationKey : @YES} completionHandler:nil]; } else { [app openURL:url]; } }
-
使用lipo查看libiPhone-lib.a文件中包含的架构
lipo -info libiPhone-lib.a Architectures in the fat file: libiPhone-lib.a are: armv7 arm64 armv7s
可知,以上libiPhone-lib.a中包含的架构有armv7、arm64和armv7s,以下以arm64为例。
-
使用URLUtility.mm生成对应架构下URLUtility.o文件
clang -c URLUtility.mm -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
-
分离libiPhone-lib.a中各架构文件
lipo libiPhone-lib.a -thin arm64 -output ./URLUtility64/libiPhone-lib64.a
-
移除对应架构中的原有URLUtility.o文件
ar -d ./URLUtility64/libiPhone-lib64.a URLUtility.o
-
将新生成的URLUtility.o文件添加到对应架构的.a中
ar -q ./URLUtility64/libiPhone-lib64.a ./URLUtility64/URLUtility.o
-
将各架构的.a文件合并生成新的libiPhone-lib.a
lipo -create ./URLUtility64/libiPhone-lib64.a ./URLUtilityv7/libiPhone-libv7.a ./URLUtilityv7s/libiPhone-libv7s.a -output ./new/libiPhone-lib.a
以上,即可替换libiPhone-lib.a中的URLUtility.o文件,从而达到移除UIWebView相关引用的目的。
可以使用Python3将以上流程用脚本实现
#!/usr/bin/evn python
# coding=UTF-8
import os
import shutil
iPhone_OS_SDK_path = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
lib_file = "libiPhone-lib.a"
arm_list = ["arm64", "armv7", "armv7s"]
origin_lib_path = "./origin_lib"
new_lib_path = "./new_lib"
def makeDir(path):
if os.path.exists(path):
print("移除原" + path + "文件")
shutil.rmtree(path)
os.makedirs(path)
print("生成新" + path + "文件")
def generateO(arm):
cmd_generate_o = "clang -c URLUtility.mm -arch " + arm + " -isysroot " + iPhone_OS_SDK_path
cmd_move_o = "mv URLUtility.o ./" + arm + "/URLUtility.o"
os.system(cmd_generate_o)
os.system(cmd_move_o)
def armThin(arm, path):
cmd_thin = "lipo libiPhone-lib.a -thin " + arm + " -output " + path + "/libiPhone-lib.a"
os.system(cmd_thin)
def arDelete(path):
cmd_ar_delete = "ar -d " + path + "/libiPhone-lib.a URLUtility.o"
os.system(cmd_ar_delete)
def arAdd(path):
cmd_ar_add = "ar -q "+ path + "/libiPhone-lib.a " + path + "/URLUtility.o"
os.system(cmd_ar_add)
def create_lib():
arm64 = arm_list[0]
armv7 = arm_list[1]
armv7s = arm_list[2]
cmd_create_lib = "lipo -create ./" + arm64 + "/" + lib_file + " ./" + armv7 + "/" + lib_file + " ./" + armv7s + "/" + lib_file + " -output " + new_lib_path + "/" + lib_file
os.system(cmd_create_lib)
print(cmd_create_lib)
print("生成新的libiPhone-lib.a,已移除UIWebView引用")
def find_API(path):
cmd_cd = "cd " + path
cmd_find = "find . | grep -v .svn | grep \"\.a\" | grep -v \"\.app\" | xargs grep UIWebView"
print(new_lib_path)
print(cmd_find)
os.system(cmd_cd)
os.system(cmd_find)
def restructure():
for arm in arm_list:
arm_path = "./" + arm
#创建文件夹
makeDir(arm_path)
#生成各架构对应的URLUtility.o文件
generateO(arm)
#分离出各架构的libiPhone-lib.a
armThin(arm, arm_path)
#移除各架构libiPhone-lib.a中原有的URLUtility.o文件
arDelete(arm_path)
#将新的URLUtility.o文件合并到libiPhone-lib.a中去
arAdd(arm_path)
#创建lib文件夹
makeDir(new_lib_path)
#合并成一个libiPhone-lib.a
create_lib()
#执行find名称,查找是否包含UIWebView相关调用
find_API(new_lib_path)
if __name__ == "__main__":
restructure()
初始文件目录为:
.
├── URLUtility.mm
└── libiPhone-lib.a
脚本运行完成后文件目录为:
.
├── URLUtility.mm
├── URLUtility64
│ ├── URLUtility.o
│ └── libiPhone-lib64.a
├── URLUtilityv7
│ ├── URLUtility.o
│ └── libiPhone-libv7.a
├── URLUtilityv7s
│ ├── URLUtility.o
│ └── libiPhone-libv7s.a
├── libiPhone-lib.a
├── new
│ └── libiPhone-lib.a
└── restructure.
其中new文件目录下的libiPhone-lib.a已实现UIWebView引用的移除,使用find
命令进行验证,发现新的libiPhone-lib.a中已不包含UIWebView相关任何代码。将该文件与工程中的对应文件进行替换,即可解决ipa包上传问题。