In the previous article (https://qiita.com/doi_daihei/items/594c15282e70c7d9235b), I talked about a project that introduced XcodeGen. The project introduced in that article used CocoaPods and Carthage to manage the library. I think it's time to move to Swift Package Manager (hereinafter SwiftPM) introduced in Xcode 9, and I will talk about the knowledge when I tried to change the library management to Swift PM without changing XcodeGen.
For the explanation of XcodeGen, please refer to Previous article and omit it in this article.
It is a tool to manage packages configured with Swift like CocoaPods and Carthage. The other strengths are as follows.
-** Made by Apple ** --There is IDE support for Xcode
Since it is made by Apple, it has a high affinity around tools including Xcode, so I think it is better to use Swift PM in the future.
Before Xcode11, it was managed by the source code Package.swift
and could only handle tool apps and server-side source code, but with the introduction of IDE support from Xcode11, it can now be completed with Xcode.
Libraries that support SwiftPM can basically be used for projects that have Package.swift
in the project root.
XcodeGen+SwiftPM
Before I started, I thought I would need Package.swift
.
However, when I finished, I was able to complete it with only the XcodeGen project configuration file project.yml
.
project.yml
name: test
packages: #First define the Package handled by SwiftPM
Reusable:
url: https://github.com/AliSoftware/Reusable
exactVersion: 4.1.1 #Version specification version is OK
RxSwift:
url: https://github.com/ReactiveX/RxSwift
minorVersion: 5.1.1 #Specified minor version ex: 5.Any 1 system is OK
Action:
url: https://github.com/RxSwiftCommunity/Action
branch: master #Branch specification
RxSwiftExt:
url: https://github.com/RxSwiftCommunity/RxSwiftExt
minVersion: 5.1.0 #Specified version or higher
maxVersion: 5.2.0 #Less than the specified version
APIKit:
url: https://github.com/ishkawa/APIKit
revision: b95a941 #Commit specification
Rswift:
url: https://github.com/mac-cain13/R.swift.Library
majorVersion: 5.2.0 #Specified major version from is OK ex:Any 5 series is OK
SwiftyUserDefaults:
url: https://github.com/sunshinejr/SwiftyUserDefaults
from: 5.0.0 #Synonymous with majorVersion
#The rest is the same writing style and detailed settings, so I will omit it
targets:
test:
type: application
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- test
- path: "test/Resources/R.generated.swift"
optional: true
type: file
dependencies:
- target: TestFramework # Embedded Framework
- package: Action
- package: Reusable
- package: Rswift
- package: RxSwift
product: RxCocoa #Specify RxCocoa inside RxSwift
- package: RxSwift
product: RxRelay #Specify RxRelay inside RxSwift
- package: RxSwift
- package: RxSwiftExt
#The rest is around the setting, so I will omit it in this article
TestFramework:
type: framework
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- TestFramework
dependencies:
- package: APIKit
- package: SwiftyUserDefaults
#The rest is around the setting, so I will omit it in this article
If you want to check the overall settings, see here.
After that, hit xcodegen
at the project root and a project with the SwiftPM library dependency resolved will be generated.
When you open the generated project with Xcode, each fetch starts, and after a while, you can check it on Project Navigator as follows.
Next, I will explain the detailed definition.
First, define each package to be handled in the entire project by referring to XcodeGen Document.
You can specify the remote destination with url
, and then specify the version etc. in detail with the parameters after that.
This time, there was nothing to handle locally, but it can be introduced as described in the above document.
project.yml
name: test
packages: #First define the Package handled by SwiftPM
Reusable:
url: https://github.com/AliSoftware/Reusable
exactVersion: 4.1.1 #Version specification version is OK
RxSwift:
url: https://github.com/ReactiveX/RxSwift
minorVersion: 5.1.1 #Specified minor version ex: 5.Any 1 system is OK
Action:
url: https://github.com/RxSwiftCommunity/Action
branch: master #Branch specification
RxSwiftExt:
url: https://github.com/RxSwiftCommunity/RxSwiftExt
minVersion: 5.1.0 #Specified version or higher
maxVersion: 5.2.0 #Less than the specified version
APIKit:
url: https://github.com/ishkawa/APIKit
revision: b95a941 #Commit specification
Rswift:
url: https://github.com/mac-cain13/R.swift.Library
majorVersion: 5.2.0 #Specified major version from is OK ex:Any 5 series is OK
SwiftyUserDefaults:
url: https://github.com/sunshinejr/SwiftyUserDefaults
from: 5.0.0 #Synonymous with majorVersion
#The rest is the same writing style and detailed settings, so I will omit it
Notation | Specified content |
---|---|
majorVersion: n.m.i or from: n.m.i |
Any specified major version n series is OK |
minorVersion: n.m.i |
Specified minor version Any n.m system is OK |
exactVersion: n.m.i or version: n.m.i |
Version specification version is OK |
branch: main |
Specified branch |
revision: xxxxxx |
Commit specification |
Next, in each Target, describe the dependency by referring to the XcodeGen document.
As a point, if the library is in a project like RxSwift
, you need to specify it further.
project.yml
targets:
test:
type: application
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- test
- path: "test/Resources/R.generated.swift"
optional: true
type: file
dependencies:
- target: TestFramework # Embedded Framework
- package: Action
- package: Reusable
- package: Rswift
- package: RxSwift
product: RxCocoa #Specify RxCocoa inside RxSwift
- package: RxSwift
product: RxRelay #Specify RxRelay inside RxSwift
- package: RxSwift
- package: RxSwiftExt
#The rest is around the setting, so I will omit it in this article
TestFramework:
type: framework
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- TestFramework
dependencies:
- package: APIKit
- package: SwiftyUserDefaults
#The rest is around the setting, so I will omit it in this article
It is also described in here, but if you go from [File]-> [Swift Packages]-> [Add Package Dependency ...] from Xcode, ProjectName.xcodeproj/project.xcworkspace/xcshareddata/Generated in swiftpm/Package.resolved
.
If you install a new library from Xcode, you need to drop the above file to be updated into project.yml
, which is annoying.
Package.resolved
defines the actual version information. It's like Podfile.lock
in CocoaPods
.The installation itself can be easily done by looking at the XcodeGen documentation. Since it can be managed on the IDE from Xcode 11, it can be expected to improve efficiency and reduce management costs.
However, as mentioned in the notes, the work of dropping it in project.yml
is more troublesome than others.
After all, I think that there are few compatible ones compared to CocoaPods and Carthage.
So, I think it's a good idea to introduce a small project that requires less library dependency.
Recommended Posts