How to create iOS Framework
애플은 코드 공유를 쉽게하기 위해 프레임워크라는 도구를 제공합니다. 뿐만 아니라 코드를 그룹화(모듈화)하고, 코드 접근을 제어하는(캡슐화) 매커니즘을 제공해줍니다. 앞서 제작해본 CocoaPod, SPM 제작 방식을 활용하여 iOS Framework를 만들어볼게요!
프레임워크 예제
본 포스팅은 raywenderlich 사이트의 'Creating a Framework for iOS' 튜토리얼을 바탕으로 작성되었습니다.
예제 파일은 아래 링크에서 확인해보실 수 있습니다.
https://www.raywenderlich.com/17753301-creating-a-framework-for-ios
Creating a Framework for iOS
Learn how to build an iOS framework, which lets you share code between apps, modularize your code or distribute it as a third-party library.
www.raywenderlich.com
Framework 생성
프로젝트 내에서 사용될 코드를 작성한다.
- 프레임워크 내부 함수의 접근제어자는 internal로 기본 설정되어있으므로 class나 외부에서 사용될 객체나 메소드 앞에 ‘public’을 붙여준다. 실제 프로젝트에서 프레임워크를 사용할 때, 프레임워크를 import 하였는데도 내부의 구조체, 함수 등이 보이지 않는다면 함수나 클래스의 공개 여부에 따라 그렇게 보인다.
프레임워크 타겟 → Build Settings → Build Options에서 build libraries for distribution을 ‘YES’로 활성화해준다.
Framework 사용
- 샘플앱에서 Add files to …를 선택하여 해당 프레임워크 경로의 프로젝트를 추가한다.
- Target → General → Frameworks and Libraries에 만든 framework 파일을 추가해준다.
XCFramework 배포
XCFramework는 Xcode에서 생성할 수 있는 바이너리 프레임워크이다.
프레임워크 아카이브
먼저 Build libraries for distribution의 build option을 Yes로 활성화시킨다.
선호하는 지원 플랫폼(iOS/Simulator/macOS)의 프레임워크를 아카이빙한다.
해당 프로젝트의 경로 안에서 터미널 명령어를 이용해 아래와 같이 입력한다.
이 명령은 다음과 같은 항목들을 입력받아 프레임워크의 아카이브를 생성할 것이다.
- -scheme CalendarControl: 스키마 사용
- -configuration Release: 빌드에 릴리즈 구성을 사용
- -destination ‘generic/platform=iOS’: 아키텍쳐 타입
- -archivePath: 주어진 폴더 경로에 아카이브를 저장
- SKIP_INSTALL: 프레임워크를 아카이브에 설치하려면 NO로 설정해야함.
- BUILD_LIBRARIES_FOR_DISTRIBUTION: 배포를 위해 라이브러리가 구축되었는지 확인하고 인터페이스 파일 생성
xcodebuild archive \
-scheme CalendarControl \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath './build/CalendarControl.framework-iphoneos.xcarchive' \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
아카이빙에 성공하면 아래 화면과 같이 build 폴더 아래에 아카이브 파일이 생성된 것을 확인할 수 있다.
Generating the XCFramework
바이너리 프레임워크인 XCFramework를 생성할 차례이다. 아래 명령어를 통해 xcframework를 생성한다.
xcodebuild -create-xcframework \
-framework './build/CalendarControl.framework-iphoneos.xcarchive/Products/Library/Frameworks/CalendarControl.framework' \
-output './build/CalendarControl.xcframework'
위 명령어 실행 후, 이전 단계에서 생성된 아카이브 파일 경로와 같은 곳에 xcframework 폴더가 생성된 것을 확인할 수 있다.
- XCFramework 폴더의 내부구조
프로젝트 내에 XCFramework 합치기
앞서 샘플앱 내에 추가시켜두었던 .xcodeproj 파일을 삭제한다. 현재 프로젝트에서 앞서 만든 CalendarControl framework에 대한 참조를 제거하기 위해서인데 더 이상 프레임워크의 소스 코드에 액세스할 필요가 없기 때문이다
xcframework를 project target → General → Frameworks, Libraries, and Embedded Content 섹션으로 드래그하여 추가시킨다.
빌드하고 실행해보자. 이전과 동일한 클래스에 액세스할 수 있음을 확인할 수 있다. 단지 프레임워크가 바이너리 파일로 바뀐 것 뿐이다.
XCFramework를 Swift Package로 배포
먼저 XCFramework 배포를 위한 swift package가 있어야 한다. 프로젝트 내에 Package.swift 파일을 하나 생성해준다. Package 클래스는 swift package의 매니페스트이다. CalendarControl 프레임워크를 스위프트 패키지로 만드려면 다음 파일의 수정이 필요하다.
아래와 같이 Package.swift에 매니패스트를 올바른 값으로 입력해준다.
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "CalendarControl",
platforms: [
.iOS(.v14)
],
products: [
.library(
name: "CalendarControl",
targets: ["CalendarControl"]),
],
targets: [
.binaryTarget(
name: "CalendarControl",
path: "./Sources/CalendarControl.xcframework")
//타겟은 독립적으로 빌드된 코드 모듈이다. 여기에 xcframework의 경로를 추가해준다.
]
)
xcframework를 프로젝트에 추가하고 Source 폴더 아래에 위치시킨다.
Swift Package 배포
스위프트 패키지 프로젝트를 열어서 메뉴 바의 Source Control → New Git Repositories 를 선택한다.
‘Create’를 선택하면 깃 리포지토리가 생성되고 코드의 초기 커밋이 생성된다.
소스 제어 탐색기를 열고 해당 패키지를 선택하여 New “ClendarControl” Remote…를 선택한다. 가시성을 비공개로 변경하거나 기본 설정을 수정할 수 있다.
설정을 완료한 후 ‘Create’을 선택하면 깃헙에 새 리포지토리가 생성되고 자동으로 코드가 푸시된다.
- 패키지에 대한 프레임워크 버전 설정
Xcode 메뉴 → 소스 제어 → push를 선택하여 해당 리포지토리에 푸시를 해준다. 태그 포함 설정도 체크하여 패키지의 버전 1.0.0이 활성화되도록 해준다.
CocoaPods Framework 배포
코코아팟 프로젝트 생성
pod lib create {프로젝트명}
.Podspec 설정
Pod::Spec.new do |s|
s.name = 'SDKPractice'
s.version = '0.1.3'
s.summary = 'Framework for SDK example project'
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://github.com/miiiiiin/SDKPractice'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'miiiiiin' => 'min.songkyung@gmail.com' }
s.source = { :git => 'https://github.com/miiiiiin/SDKPractice.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.swift_versions = ['4.2', '5.0']
#s.ios.deployment_target = '13.0'
s.platform = :ios, "9.0"
s.frameworks = 'UIKit'
s.requires_arc = true
#s.source_files = 'SDKPractice/Classes/**/*'
s.dependency 'GoogleSignIn'
s.static_framework = true
s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
#s.module_name = 'SDKPractice'
#s.preserve_paths = 'SDKPractice/Frameworks'
s.vendored_frameworks = 'Frameworks/SDKSample.framework'
# s.resource_bundles = {
# 'SDKPractice' => ['SDKPractice/Assets/*.png']
# }
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
end
프레임워크를 pods에 포함하고 싶을 경우, Frameworks라는 폴더를 하나 만들어 .framework 파일을 이동시킨다. 그리고 그 경로를 s.vendored_frameworks 에 입력해준다. 또한 이 상태로 pod lib spec 검증 과정을 거치면 시뮬레이터 관련 에러가 나타날 수도 있는데 이 경우에는 s.pod_target_xcconfig와 s.user_target_xcconfig를 arm64로 설정해주면 된다.
s.static_framework = true
s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
s.vendored_frameworks = 'Frameworks/SDKSample.framework'
추가적으로 타 코코아팟 라이브러리의 의존성을 추가하고 싶다면 아래와 같이 설정해주면 된다.
// 예시
s.dependency 'GoogleSignIn'
.PodSpec 검증
pod spec lint
다음 명령어를 실행하여 해당 라이브러리의 .podspec 파일에 이상이 없는지 확인한다. 해당 명령어를 통해 .podspec 파일에 명시된 값들에 대한 유효성 검증이 진행된다.
코코아팟 배포
유효성 검증이 완료되면 아래 명령어를 실행하여 코코아팟 라이브러리 배포를 진행한다.
pod trunk register {이메일} {이름}
pod trunk push {라이브러리명}.podspec
배포완료된 팟의 상세정보 및 저장소이다.
https://github.com/miiiiiin/SDKPractice
miiiiiin/SDKPractice
Contribute to miiiiiin/SDKPractice development by creating an account on GitHub.
github.com
참고
- https://kka7.tistory.com/137
- http://minsone.github.io/programming/distributing-binary-frameworks-as-swift-packages-1
- https://medium.com/@er.mayursharma14/how-to-create-xcframework-855817f854cf
- https://www.raywenderlich.com/17753301-creating-a-framework-for-ios
- https://developer.apple.com/documentation/swift_packages/distributing_binary_frameworks_as_swift_packagesKakaoAd/kakao-ad-ios
- https://github.com/CocoaPods/Specs/blob/master/Specs/a/0/c/KakaoSDK/2.3.2/KakaoSDK.podspec.json
- https://velog.io/@wimes/SDK-뼈대-만들어보기
- https://developer.zendesk.com/embeddables/docs/ios_support_sdk/sdk_addzendesk/support_sdk_ios
- https://github.com/zendesk/zendesk_sdk_ios.git
'iOS' 카테고리의 다른 글
AWS S3에 이미지 업로드 하기 (0) | 2022.03.25 |
---|---|
Apple Enterprise 와 Apple Business Manager (0) | 2021.10.20 |
스위프트 패키지 매니저(Swift Package Manager) 라이브러리 만들기 (0) | 2021.07.09 |
iOS CocoaPods 라이브러리를 만들어보자 (0) | 2021.07.08 |
UICollectionView에 대해 알아보자(1) (2) | 2020.11.08 |