1. CPU Architecture
- 아이폰은 기종에 따라 다른 아키텍처의 CPU를 사용함.
- 빌드를 하면 Execute file이 생성되고 이 파일을 CPU에서 읽기 때문에 이에 맞는 아키텍처 생성이 필요함.
- 기종별 아키텍처
- armv7 : ~ iPhone 5s
- arm64 : iPhone 5s ~
- x86_64 : 64bit 기기에 대응하는 simulator, mac
- 우리는 iOS 13부터 시작하므로 13 버전은 iPhone SE, 6s부터 시작이므로 arm64로만 빌드하면 될 것 같음.
- Build Active Architecture Only
- Release : Yes < arm64
- Debug : No < simulator도 지원해야 함.
2. Framework
- Static Framework
- 구성 : source file + static lib + static linker
- static linker를 통해 static lib의 코드가 execute file로 들어가 heap 메모리에 상주
- static lib이 복사되므로 static framework를 여러 프레임워크에서 사용하면 코드 중복 발생
- 장점 : 런타임 속도가 빠름, inline 개념
- 단점 : 메모리 많이 사용, 여러 모듈에서 동일한 static lib을 임포트하면 그 횟수만큼 라이브러리가 복사되기 때문에 app size 측면에서의 용량 늘어나게 됨, 컴파일 속도 오래 걸림
- Dynamic Framework
- 구성 : source file + dynamic lib references + dynamic lib + static linker
- 파일이 아닌 주소를 execute file에 저장하고 static linker를 통해서 stack으로 필요한 라이브러리들을 불러와서 사용하는 형태
- 주소 정보들만 heap에 상주 (스태틱은 라이브러리 코드가 힙 메모리에 상주)
- 장점 : 컴파일 속도가 상대적으로 빠르고 메모리 효율적 사용
- 단점 : 런타임 속도가 느림(왜냐 런타임에 프레임워크를 로드하기 때문)
3. embeded 설정
- dynamic lib의 경우 Targets > General > Frameworks, Libraries, and Embedded Content의 각 항목에 대해 Do Not Embeded로 설정하면 안 됨. 왜냐 dynamic lib들은 동적으로 런타임에 로딩되기 때문에 embeded 된 형태로 사용해야 함.
- static lib은 두 가지로 나뉘게 됨. 빌드할 때 이미 라이브러리 내 코드들이 복사되는 형태이므로 do not embed해도 상관이 없지만! 리소스 번들을 사용해야 하는 경우 embeded 방식으로 선택해야 함. embeded 방식으로 사용하게 되면 코드 복사본이 두 개 생김. 하나는 빌드 시 이 라이브러리를 import하여 사용하는 곳에서 한 번 복사되고 애플리케이션 패키지 내에 프레임워크 형태로 하나 더 존재함.
4. XCFramework ?
- 기존의 fat framework (x86_64 + armv7 + arm64) 형태는 하나의 프레임워크 안에 모든 빌드 아키텍처가 들어가 있기 때문에 용량도 커지고 불필요한 작업도 들어감
- 약간 다른 의견을 드리자면 fat framework 에서 용량이 큰 문제는 xcframework도 똑같이 가지고 있습니다.
fat framework로 빌드하더라도 빌드타임에 필요한 아키텍쳐 바이너리만 추출하여 빌드하기 때문에 단점이라 볼 수 없습니다.
기존에는 fat 라이브러리 하나의 파일에서도 armv7, arm64는 iOS용, x86(i386), x86_64는 macOS용으로 구분이 되었습니다.
기존에도 하나의 파일이었고, iOS용과 시뮬레이터용 파일이 별도로 존재하는 것은 아니었습니다.
(별도로 존재할 경우 iOS 디바이스용 라이브러리에는 x86, x86_64가 포함되지 않았습니다.)
xcframework가 나온 배경은 실리콘 기반의 맥 출시와 관련이 있습니다.
실리콘 기반의 맥이 출시되면서 arm64 아키텍쳐가 iOS와 서로 겹치기 때문에 하나의 fat 파일로 만들지 못하는 문제를 해결하기 위해 고안된 방법입니다.
- 약간 다른 의견을 드리자면 fat framework 에서 용량이 큰 문제는 xcframework도 똑같이 가지고 있습니다.
- 반면 XCFramework는 각각의 아키텍처를 분리함.
5. XCFramework 구현하기
- XCode에서 create > Framework로 프레임워크 프로젝트 생성
- 만들어진 프로젝트 설정
- Targets > Build Settings > Build Options > Build Libraries for Distribution > Yes
- Targets > Build Settings > Linking > Mach-O Type > 원하는 동적/정적 라이브러리로 설정
- Targest > Signing & Capabilities > Automatically manage signing 체크 해제, Bundle Identifier 지우고 엔터
- 만들 함수 만든 후 cmd 창에서 내 프로젝트 위치로 이동
- 아래 코드 세 개를 순차적으로 각각 실행해줌. 첫 번째는 archiving을 하여 시뮬레이터용 바이너리 파일(.xcarchive)를 만든 것이고 두 번째는 실제 아이폰용 바이너리 파일을 마지막은 두 바이너리 파일들을 합쳐서 하나의 XCFramework로 묶은 것임.
// simulatorxcodebuild archive -scheme 프로젝트명 \-archivePath './build/iphone-simulator.xcarchive' \-sdk iphonesimulator \SKIP_INSTALL=NO \BUILD_LIBRARY_FOR_DISTRIBUTION=YES// iphone osxcodebuild archive -scheme 프로젝트명 \-archivePath './build/iphone.xcarchive' \-sdk iphoneos \SKIP_INSTALL=NO \BUILD_LIBRARY_FOR_DISTRIBUTION=YES// xcframeworkxcodebuild -create-xcframework \-framework "./build/iphone.xcarchive/Products/Library/Frameworks/프로젝트명.framework" \-framework "./build/iphone-simulator.xcarchive/Products/Library/Frameworks/프로젝트명.framework" \-output "./xcframework/만들_프레임워크명.xcframework"
- 만들어진 "./xcframework/프레임워크명.xcframework" 파일을 복사해서 테스트하기 위한 프로젝트에 Frameworks 폴더를 생성하고 하위에 프레임워크명.xcframework 폴더만 넣어줌.
- xcode에도 넣어주고 테스트용 프로젝트 > Targets > General > Frameworks, Libraries and Embeded Content에서도 추가해줌. Embeded & Sign으로 설정해줌. (아직 dynamic framework이기 때문)
6. static framework 만들기
- 위 코드로 만든 프레임워크 프로젝트에서 Targets > Build Settings > Mach - O > static 으로 변경.
7. 한 곳에서 작업하기
- File > New > Workspace > 이름 지정 > 생성 (폴더는 프레임워크, 프레임워크를 테스트할 프로젝트 있는 폴더에서 생성)
- 프레임워크, 프레임워크를 테스트할 프로젝트 모두 닫기
- 만든 워크스페이스 열고 File > Add File to “workspace 이름” > 프레임워크, 프레임워크를 테스트할 프로젝트의 .xcodeproj 파일 추가
- 그 다음 왼쪽 hierarchy 창에서 프레임워크를 테스트할 프로젝트 누르고 Targets > General > Frameworks, Libraries, and Embeded Content에서 프레임워크 추가 후 Do not Embed로 속성 설정
- 해당 창의 상단에서 Build Phases > Link Binary With Libraries > 프레임워크 추가
- framework 내부에 .xib 파일이 있다면 그대로 복사해서 프레임워크를 테스트할 프로젝트에 넣어주고 하는게 훨씬 나음. 찾아보니 번들을 만들어서 그걸 또 프로젝트에 넣어주면 되는 것 같기는 한데 저는 안 됐습니다… 차라리 xib 파일을 최소화하고 연동할 때 넣어주는 것이 나을 것 같습니다. (번들 방식 : iOS static library)
8. code signing
framework의 경우 signing 해 줄 필요가 없는 것 같음.
프레임워크 > Targets > Signing & Capabilities 에서 Automatically manage signing 체크 해제한 후 Bundle Identifier 지우고 Team을 none으로 변경
https://github.com/Carthage/Carthage/issues/1378
'CS > iOS, Swift' 카테고리의 다른 글
[iOS] XCFramework build script (0) | 2023.04.06 |
---|---|
[iOS] XCFramework private repository에 cocoapod으로 배포하기 (0) | 2023.04.06 |
[iOS] Private Repository에 CocoaPod Framework 올리기 (0) | 2023.04.06 |
[iOS] xcode, bitbucket 연동 (0) | 2023.02.14 |
[iOS] IDFA 값 받아오기 (0) | 2023.02.14 |