博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift Package Manager使用总结
阅读量:7174 次
发布时间:2019-06-29

本文共 6960 字,大约阅读时间需要 23 分钟。

一、简介

Swift Package Manager(以下简称SPM)是苹果在swift3.0中加入的一个包管理工具,用于处理模块代码的下载、编译和依赖关系等。跟CocoaPods和Carthage功能类似,不过比这两个更简洁,代码的侵入性更小,也不需要额外安装工具。

需要注意的是,SPM在swift4.0中重新设计了API,所以你需要确定你当前使用的swift版本,否则很可能会出现build失败的情况,以下代码都是基于swift4.0版本。

二、使用教程

既然是包管理,所以我们的操作都是以包的形式,依赖的第三方库都会当成一个个单独的包来处理,依赖包可以嵌套。

SPM包含两种包:可执行的二进制包(executable)和静态库包(Library),两者唯一的区别就是前者会生成二进制可执行文件,可以直接用命令行执行。如果创建的是Library,用命令行执行会提示没有可执行文件,这个时候只需要在Sources/目录下创建一个main.swift文件就可以执行了。

1、通过命令创建包:

$ mkdir SPMDemo    $ cd SPMDemo         $ swift package init --type executable(or library)  //初始化包,不带参数的话默认是LibraryCreating executable package: SPMDemoCreating Package.swiftCreating .gitignoreCreating Sources/Creating Sources/main.swiftCreating Tests/$ swift build    //编译并生成可执行的二进制文件Compile Swift Module 'SPMDemo' (1 sources)Linking ./.build/debug/SPMDemo$ swift run 	//执行生成的文件Hello, world!   //执行效果复制代码

2、加入依赖包

我们需要在前面创建的包中使用第三方库(这里以SwiftyJSON为例),编辑Package.swift文件:

// swift-tools-version:4.0// The swift-tools-version declares the minimum version of Swift required to build this package.import PackageDescriptionlet package = Package(    name: "SPMDemo",    dependencies: [        // Dependencies declare other packages that this package depends on.        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"),	//第三方库url和版本号    ],    targets: [        // Targets are the basic building blocks of a package. A target can define a module or a test suite.        // Targets can depend on other targets in this package, and on products in packages which this package depends on.        .target(            name: "SPMDemo",            dependencies: ["SwiftyJSON"]),	//依赖的包名称    ])复制代码

注:关于dependencies的格式定义可以看有详细说明文档,可以指定分支、具体的commit编号、版本范围等等。

然后我们检验一下引入的依赖包是否可用,编辑Sources目录下的main.swift文件:

import SwiftyJSON	//引入模块let json = JSON(["name":"Jack", "age": 25])print(json)print("Hello, world!")复制代码

保存之后我们再run一下:

$ swift runFetching https://github.com/SwiftyJSON/SwiftyJSON.gitCloning https://github.com/SwiftyJSON/SwiftyJSON.gitResolving https://github.com/SwiftyJSON/SwiftyJSON.git at 4.0.0Compile Swift Module 'SwiftyJSON' (1 sources)Compile Swift Module 'SPMDemo' (1 sources)Linking ./.build/x86_64-apple-macosx10.10/debug/SPMDemo{  "name" : "Jack",  "age" : 25}Hello, world!复制代码

可以看到输出了我们的json结构体,说明引入依赖包成功了!

注:第一次run的时候SPM会先将依赖的库克隆下来并编译好放在.build隐藏文件夹中,如果把这个文件夹删除重新run,会重新下载。

3、现在我们来试试自己定义一个库作为其他项目的依赖包

$ mkdir MyLib    $ cd MyLib         $ swift package init	//初始化包,不带参数的话默认是LibraryCreating library package: MyLibCreating Package.swiftCreating README.mdCreating .gitignoreCreating Sources/Creating Sources/MyLib/MyLib.swiftCreating Tests/Creating Tests/LinuxMain.swiftCreating Tests/MyLibTests/Creating Tests/MyLibTests/MyLibTests.swift复制代码

创建Library的话默认是没有main.swift文件的,Sources目录下只有一个MyLib.swift文件,它给我们定义了一个结构体,但并不是public的,我们知道swift中只有被public和open修饰才能被其他模块访问,所以我们把它改成public:

public struct MyLib {    var text = "Hello, MyLib!"    public var num:Int    public init() {        num = 2    }}复制代码

然后我们build一下,确保我们的Library能顺利编译通过。

因为SPM依赖包必须使用git url和版本号,所以我们需要为我们的库创建一个git仓库并提交代码和打tag:

$ git init$ git add .$ git commit -m "Initial Commit"$ git tag 1.0.0复制代码

接下来修改前面的Package.swift文件,加入我们的Library:

dependencies: [        // Dependencies declare other packages that this package depends on.        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"),        .package(url: "./MyLib", from: "1.0.0")    //因为没有推送到远程仓库,所以这里用相对路径,from就是我们刚才打的tag    ],    targets: [        // Targets are the basic building blocks of a package. A target can define a module or a test suite.        // Targets can depend on other targets in this package, and on products in packages which this package depends on.        .target(            name: "SPMDemo",            dependencies: ["SwiftyJSON","MyLib"]),      //添加依赖包名    ]复制代码

然后我们再检验一下依赖包是否可用,编辑main.swift文件:

import SwiftyJSONimport MyLib//SwiftyJSONlet json = JSON(["name":"Jack", "age": 25])print(json)//自定义库let lib = MyLib()print(lib)复制代码

然后我们再run一次看看:

{  "name" : "Jack",  "age" : 25}MyLib(text: "Hello, MyLib!”, num: 2)复制代码

结果输出了我们自定义的库中结构体的内容,说明我们引入自定义依赖包成功了!

三、如何在iOS工程中使用SPM

除了macOS以外,目前SPM不支持苹果其他平台,所以如果想替换Pods或者Carthage还是谨慎一点,等苹果完全支持iOS以后再切换过来吧。不过我们可以以引入子工程的方式在iOS项目中使用SPM,具体步骤如下:

1、创建新的iOS项目或者使用已存在的项目

2、将该工程初始化为SPM(swift package init)

3、创建一个空的依赖源文件和路径,因为创建xcodeproj文件的时候需要至少一个源文件,这里我在dep-sources路径下创建一个Dependencies.swift文件:

$ mkdir dep-sources$ cd dep-sources/$ touch Dependencies.swift复制代码

4、修改Package.swift文件,加入依赖库并设置target为新的名字,否则会跟iOS工程的target重名,这里我改为Dependencies,然后在target中设置第3步的路径

// swift-tools-version:4.0// The swift-tools-version declares the minimum version of Swift required to build this package.import PackageDescriptionlet package = Package(    name: "Dependencies",    products: [        // Products define the executables and libraries produced by a package, and make them visible to other packages.        .library(            name: "Dependencies",            type: .static,            targets: ["Dependencies"]),    ],    dependencies: [        // Dependencies declare other packages that this package depends on.        // .package(url: /* package url */, from: "1.0.0"),        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"),        .package(url: "https://github.com/Alamofire/Alamofire.git", from: "4.6.0")    ],    targets: [        // Targets are the basic building blocks of a package. A target can define a module or a test suite.        // Targets can depend on other targets in this package, and on products in packages which this package depends on.        .target(            name: "Dependencies",            dependencies: ["SwiftyJSON","Alamofire"],            path: "dep-sources" //源文件路径        )    ])复制代码

5、执行swift package generate-xcodeproj命令,这里会生成Dependencies.xcodeproj

$ swift package generate-xcodeprojFetching https://github.com/SwiftyJSON/SwiftyJSON.gitFetching https://github.com/Alamofire/Alamofire.gitCloning https://github.com/SwiftyJSON/SwiftyJSON.gitResolving https://github.com/SwiftyJSON/SwiftyJSON.git at 4.0.0Cloning https://github.com/Alamofire/Alamofire.gitResolving https://github.com/Alamofire/Alamofire.git at 4.6.0generated: ./Dependencies.xcodeproj复制代码

6、打开iOS工程,将第5步生成的project拖入工程作为sub-project,然后添加依赖的framework就可以了(xcode9经常莫名其妙抽风,建议做完后关闭重新打开工程)

7、验证引入包是否成功

四、可能碰到的问题

1、no such module

$ swift buildCompile Swift Module 'SPMDemo' (1 sources)/SPMDemo/Sources/SPMDemo/main.swift:2:8: error: no such module 'MyLib'import MyLib复制代码

这有可能是你只加入了依赖包的路径而没有在target中加入模块名称

targets: [        // Targets are the basic building blocks of a package. A target can define a module or a test suite.        // Targets can depend on other targets in this package, and on products in packages which this package depends on.        .target(            name: "SPMDemo",            dependencies: ["SwiftyJSON"]),      //缺少“MyLib”    ]复制代码

还有一种情况是更新了依赖包,但是没有构建到.build目录下,这个时候只要把.build文件删除,重新构建一次就可以了。有什么问题欢迎留言讨论!

转载于:https://juejin.im/post/5a3cc9a351882560b76c5ddf

你可能感兴趣的文章
集群增量会话管理器——DeltaManager
查看>>
MySql的安装与卸载
查看>>
探知互联网未来 关注中国开放网络峰会
查看>>
云安全是否能跟上云存储的爆炸性增长
查看>>
大数据:安全分析产品的发展重点
查看>>
微软认知服务为企业带来云AI
查看>>
关于linux下的mysql配置流程以及项目发布的流程
查看>>
汇总站外seo方法和做法?
查看>>
选择使用正确的 Markdown Parser
查看>>
SaaS的中国式成功 中企开源服务保障体系揭秘
查看>>
大数据资源争夺战此起彼伏 对用户而言是福是祸?
查看>>
Java 高效压缩zip
查看>>
什么是自行车码表?自行车码表工作原理?自行车码表安装设置?
查看>>
《MATLAB/Simulink系统仿真超级学习手册》——导读
查看>>
微软准备开源 PowerShell!
查看>>
AMD 向 LibreOffice 贡献 GPU 代码 电子表格速度提升500倍
查看>>
J-SUtil-1.1.3_3 支持对象关联映射查询
查看>>
Opera 32 桌面版发布,新增动态背景功能
查看>>
《精解Windows8》——2.4 关闭计算机
查看>>
《嵌入式 Linux C 语言应用程序设计(修订版)》——2.4 嵌入式Linux调试器GDB的使用...
查看>>