#Debug Record:Xcode 13、iOS 15、Mac mini(M1 芯片)兼容支持

3,844 阅读4分钟

最近换了 Mac mini (M1, 2020) 办公,升级系统、安装新版 Xcode 后碰到一些问题,记录一下。

1. iOS 项目跑不起来了。

1.1 工程编译失败

两个主要维护的项目都碰到 build 直接报错:

ld: warning: ignoring file /Users/xxx/Library/Developer/Xcode/DerivedData/FFer-Client-blhojnexdkcciegjsxqvplzhfump/Build/Products/Debug-iphonesimulator/AFNetworking/libAFNetworking.a, building for iOS Simulator-x86_64 but attempting to link with file built for iOS Simulator-arm64
ld: warning: ignoring file /Users/xxx/Library/Developer/Xcode/DerivedData/FFer-Client-blhojnexdkcciegjsxqvplzhfump/Build/Products/Debug-iphonesimulator/AliyunOSSiOS/libAliyunOSSiOS.a, building for iOS Simulator-x86_64 but attempting to link with file built for iOS Simulator-arm64
...还有许多其他类似的 第三方库 链接问题信息
ld: warning: object file (/Users/xxx/Projects/FFer-Client/Pods/OneKit/OneKit/BaseKit/Decorator/Vendor/libEncryptor.a(libBDEncryptor-iOS.a-x86_64-master.o)) was built for newer iOS Simulator version (10.3) than being linked (10.0)
ld: warning: object file (/Users/xxx/Projects/FFer-Client/Pods/TXLiteAVSDK_Player/TXLiteAVSDK_Player/SDK/TXLiteAVSDK_Player.framework/TXLiteAVSDK_Player(libvoicechanger.o)) was built for newer iOS Simulator version (13.2) than being linked (10.0)
ld: warning: object file (/Users/xxx/Projects/FFer-Client/Pods/TXLiteAVSDK_Player/TXLiteAVSDK_Player/SDK/TXLiteAVSDK_Player.framework/TXLiteAVSDK_Player(trae_voip.o)) was built for newer iOS Simulator version (13.2) than being linked (10.0)
...
Undefined symbols for architecture x86_64
项目中一些使用到第三方库的关联 .o 文件
...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Undefined symbol: _OBJC_CLASS_$_SDWebImageDownloader
Undefined symbol: _OBJC_CLASS_$_AFHTTPRequestSerializer
Undefined symbol: _AFQueryStringFromParameters
Undefined symbol: _OBJC_CLASS_$_WYPopoverController
Undefined symbol: _AFNetworkingTaskDidSuspendNotification
Undefined symbol: _AFNetworkingTaskDidResumeNotification
...

可以看出是跟芯片架构有关,而且都是第三库中的。因为第三方库都是为原来的 x86_64 架构编译,而现在都是链接到新的 arm64 模拟器。拿关键字搜索一下,最终通过在 Podfile 中添加配置使编译所有架构:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      # 处理 M1 芯片上不支持 模拟器 运行问题:不仅仅编译活跃的架构,反之就是 i386、x86_64、arm64 等架构都编译。
      config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
    end
  end
end

也有提到可以删除 Project/TARGETS 自定义 Building Settings 中的 VALID_ARCHS,我验证没有效果。更多方案参考:mirari.cc/2021/07/28/…

1.2 项目打包链接失败

ld: building for iOS Simulator, but linking in object file built for iOS, file '/Users/xxx/Pods/mob_sharesdk/ShareSDK/ShareSDK.framework/ShareSDK' for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

同前面的问题类似,链接的文件是 arm64 架构的,解决方法为在 TARGETS > Build Settings > Architectures > Excluded Architectures 中添加配置项:Any iOS Simulator SDK : arm64。即对于模拟器不包括 arm64 架构。(后来验证了一下,实际上前面一个问题的解决方法也可以解决这个问题,概括起来就是 VALID_ARCHS 与 Excluded Architectures 不要矛盾)

参考:StackOverflow:Xcode 12, building for iOS Simulator, but linking in an object file built for iOS, for architecture 'arm64'

2. UI 异常。

同样的代码,使用 Xocde 13 跑 iOS 15 模拟器发现一些 UI 异常了。

2.1 表格视图 header/footer 多出一定距离高度(22pt)

image.png

对应的也导致底部 footer 被裁切内容显示不全,排查为 iOS 15 起新增的 sectionHeaderTopPadding 属性导致:

/// Padding above each section header. The default value is `UITableViewAutomaticDimension`.
@property (nonatomic) CGFloat sectionHeaderTopPadding API_AVAILABLE(ios(15.0), tvos(15.0), watchos(8.0));

默认值为 UITableViewAutomaticDimension,不知道为什么会设置为 22,文档中没有进一步的解释,解决方法手动配置为 0:

if (@available(iOS 15, *)) {
	  _imChatListVC.tableView.sectionHeaderTopPadding = 0;
}

2.2 导航栏默认变为透明

image.png

通过配置导航栏样式解决:

- (void)configNavigationAppearance {
    if (@available(iOS 13.0, *)) {
        UINavigationBarAppearance *apperance = [[UINavigationBarAppearance alloc] init];
        [apperance configureWithOpaqueBackground];
        [[UINavigationBar appearance] setStandardAppearance:apperance];
        [[UINavigationBar appearance] setScrollEdgeAppearance:apperance];
    }
}

/* 
源文档:
<https://developer.apple.com/documentation/uikit/uinavigationbar/3198028-standardappearance>
 */

/// Describes the appearance attributes for the navigation bar to use when it is displayed with its standard height.
@property (nonatomic, readwrite, copy) UINavigationBarAppearance *standardAppearance UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(13.0), tvos(13.0));
/// Describes the appearance attributes for the navigation bar to use when it is displayed with its compact height. If not set, the standardAppearance will be used instead.
@property (nonatomic, readwrite, copy, nullable) UINavigationBarAppearance *compactAppearance UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(13.0));
/// Describes the appearance attributes for the navigation bar to use when an associated UIScrollView has reached the edge abutting the bar (the top edge for the navigation bar). If not set, a modified standardAppearance will be used instead.
@property (nonatomic, readwrite, copy, nullable) UINavigationBarAppearance *scrollEdgeAppearance UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(13.0));
/// Describes the appearance attributes for the navigation bar to use when it is displayed with its compact heights, and an associated UIScrollView has reached the edge abutting the bar. If not set, first the scrollEdgeAppearance will be tried, and if that is nil then compactAppearance followed by a modified standardAppearance.
@property(nonatomic,readwrite, copy, nullable) UINavigationBarAppearance *compactScrollEdgeAppearance UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(15.0));

通过文档看出 iOS 13 开始就可以分别针对配置一些标准高度、紧凑模式(应该是导航栏被顶起只显示一小行 title 的状态)、以及滚动视图滚到导航栏下时的样式属性。iOS 15 又新增了紧凑模式滚动视图靠近导航栏边缘时的样式,估计可能是顺道一起调整了默认行为吧。

参考: StackOverflow: iOS 15 Navigation Bar Transparent

3. 没有支持 M1 芯片的软件无法打开

例如 印象笔记 9.5.12 版本:

image.png

点击安装,输入密码,然而:

image.png

经过搜索尝试,最终通过切换网络解决(苹果要是能明确提示 ‘An network error has occurred..’ 就更好了)。也有提到可以尝试重启。

祝好运。