更新

  • 2020/06/06 补充 Unity 修复版本
  • 2020/01/12 初次发布

介绍

苹果在审核拒约时给出了以下信息:

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.

但是项目内并未使用 UIWebView API,尝试使用 Unity 构建一个空工程上传到 QuickSDK 进行预先检查,发现依然存在 UIWebView API 调用。

搜索后发现 Unity 已在 2017.4, 2018.4, 2019.2, 2019.3, 2020.1 中修复:

如果可以升级版本,推荐优先升级到对应的 Unity 修复版本:

但是旧版本如 Unity 5.6 就需要自行处理了

环境

  • Unity 5.6.6f2
  • macOS 10.14.6
  • Xcode 11.0

解决方案

虽然 Unity 官方不准备在旧版本修复此 Bug,但是在问题描述中阐述了具体细节:在 PlatformDependent/iPhonePlayer/URLUtility.mm 中使用 UIWebView 处理游戏内链接。

搜索后找到了一个现成的解决方案,经过测试后可用:

下面记录一下实践过程并补充一些相关信息。

保存源文件

首先将以下内容保存为 URLUtility.mm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#import <UIKit/UIKit.h>

using namespace std;

namespace core {
    template <class type>
    class StringStorageDefault {};
    template <class type,class type2>
    class basic_string {
    public:
        char *c_str(void);
    };
}

void OpenURLInGame(core::basic_string< char,core::StringStorageDefault<char> > const&arg){}

void OpenURL(core::basic_string<char,core::StringStorageDefault<char> >const&arg){
    const void *arg2= &arg;
    UIApplication *app = [UIApplication sharedApplication];
    NSString *urlStr = [NSString stringWithUTF8String:(char *)arg2];
    NSURL *url = [NSURL URLWithString:urlStr];
    [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];
    [app openURL:url];
}

编译

原文只使用了 arm64 架构,实际上通过 file 命令查看 libiPhone-lib.a 是三个架构:

1
2
3
4
5
$ file libiPhone-lib.a
libiPhone-lib.a: Mach-O universal binary with 3 architectures: [arm_v7:current ar archive] [arm_v7s]
libiPhone-lib.a (for architecture armv7):    current ar archive
libiPhone-lib.a (for architecture arm64):    current ar archive
libiPhone-lib.a (for architecture armv7s):    current ar archive

因此在编译时建议三种架构都编译,否则在替换时会提示缺失符号问题。

1
clang -c URLUtility.mm -arch arm64 -arch armv7 -arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk

执行完当前目录会生成 URLUtility.o 目标文件。

注意:-isysroot 指定的 SDK 路径一定是当前工程使用的 Xcode 版本,特别是当机器上存在多个 Xcode 版本时要注意。

替换

首先要明确,libiPhone-lib.a 是一个存档文件,内部保存了许多目标文件,可以使用 ar -tv libiPhone-lib.a 显示内容。

1
2
3
4
# 删除原有的 URLUtility.o
ar -d libiPhone-lib.a URLUtility.o
# 在文件最后增加 URLUtility.o
ar -q libiPhone-lib.a URLUtility.o

ar 命令的具体使用方法可以通过执行 man ar 查看。

建议

可以将以上步骤放到构建流程里,每次出包的时候自动将 Xcode 工程内的 libiPhone-lib.a 替换。