Xcode update

UIButton, XCFramework

Posted by poos on September 28, 2020

背景

开个文章记录一下 Xcode 升级碰到的故事~ 以后不断更新。

更新了一下 Xcode 12 的故事。

UIButton

一个神奇的问题:

Xcode 11.5+ 使用 Xcode 直接 run 真机在(iOS 13.4+)会出现。但是关掉之后点击手机中的图标直接打开就没有问题。

使用 Xcode 11.4 以下没有问题。

https://developer.apple.com/forums/thread/652941

测试了在最新 Xcode 12.3 仍然没有修复。

为了能够继续愉快的debug,暂时的修改是使用 runtime 再次设置了一下 title:

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
#pragma mark - Debug Only -

#if DEBUG

#import <objc/runtime.h>

@interface UIButton ()
@end

@implementation UIButton (Debug)

+ (void)load {
    Method original = class_getInstanceMethod(UIButton.class, @selector(setTitle:));
    Method swizzled = class_getInstanceMethod(UIButton.class, @selector(setAllTitle:));
    method_exchangeImplementations(original, swizzled);
}

- (void)setAllTitle:(NSString *)title {
    [self setAllTitle:title];

    [self setTitle:title forState:UIControlStateNormal];
    [self setTitle:title forState:UIControlStateHighlighted];
    [self setTitle:title forState:UIControlStateDisabled];
    [self setTitle:title forState:UIControlStateSelected];
}
@end

#endif

Universal Framework

进入到 Xcode 12 时代之后,iphone simulator 的打包也会提供 arm64 的编码了,且 arm64 不通用,所以使用原来的合并 framework 的时候就会出现问题。虽然可以在合并之前去掉模拟器的 arm64 符号,但是如果到了 Xcode 12.2 新的隐患就会出现。

Xcode 12.2 是最后一个默认支持 Universal Framework 的版本,如果使用 >= Xcode12.3 在模拟器运行就会抛出错误

1
Building for iOS Simulator, but the linked and embedded framework 'My.framework' was built for iOS + iOS Simulator.

那解决这个问题的终极方法就是使用新的 xcframework,稍后介绍如果打包和使用。

但是还有一种改变 error 到 warning 的方式,就是去 BuildSettings -> Validate Workspace 设置 Yes

Xcode 12.3: Building for iOS Simulator, but the linked and embedded framework was built for iOS + iOS Simulator [duplicate]

XCFramework

使用 xcframework 一个是因为 使用 >= Xcode12.3 在模拟器运行, 还有一个是M1电脑只能用 Xcode12+,且要支持模拟器运行必须打包arm64符号。虽然这两个都有解决方法,但都不是最终的完美解决。

完美解决就是使用 xcframework :

xcode-xcframeworks

xcfamework 使用文件夹直接区分了framework。

1
2
3
4
Example.xcframework
|- Info.plist
|- ios-arm64
|- ios-arm64_x86_64-simulator
BUILD_LIBRARY_FOR_DISTRIBUTION

如果要设置 BUILD_LIBRARY_FOR_DISTRIBUTION YES,有可能需要到项目去设置

build 脚本

为了 build 的方便,也可以使用命令行去build。

1
2
3
4
5
6
7
xcodebuild archive -scheme Example_iOS -destination="iOS" -archivePath build/iphoneos -derivedDataPath build/iphoneos -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

xcodebuild archive -scheme Example_iOS -destination="iOS Simulator" -archivePath build/iphonesimulator -derivedDataPath build/iphonesimulator  -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

rm -rf build/Example.xcframework

xcodebuild -create-xcframework -framework build/iphoneos.xcarchive/Products/Frameworks/Example.framework -framework build/iphonesimulator.xcarchive/Products/Frameworks/Example.framework -output build/Example.xcframework
在项目的使用

有可能需要设置 General -> Frameworks, Libraries, and Embedded ContentEmbed and Sign

最后

More issue waiting to be discovered..