使用Swift Package Manager管理项目

998 阅读3分钟
原文链接: blog.csdn.net

今天来讲讲swift的代码资源库管理工具——Swift Package Manager,下面简称SPM。并对上一篇今天开始写swift服务器(一)做一些关于项目管理上的纠正。上篇讲到,因为SPM管理,如果source文件中发生变动,会造成无法正常更新或添加库或框架的问题,故使用workspace管理项目。但是,使用workspace管理,会出现部分C语言的库无法链接的问题,可能本人能力有限,没有找到解决方法。同时,因为perfect框架有提供Perfect Assistant这个工具用来构建不同环境下的代码,可用于测试和发布,但是这个工具不支持workspace,只支持project。所以,只能改换使用project写项目,只能使用SPM进行管理。经过这段时间的研究,总结一下经验。下面以建立一个project为例来向大家说明。

首先指定一个文件夹创建一个空的项目

[plain] view plain copy print?
  1. <span style="font-size:18px;">swift package init --type executable</span>  
swift package init --type executable

这时创建出来的空项目的目录结构为

[plain] view plain copy print?
  1. Package.swift  
  2. Source:  
  3.      main.swift  
  4. Test:  
Package.swift
Source:
     main.swift
Test:

如果,我们随意变动这个目录结构,都会造成之后build出问题,导致无法使用SPM管理。对于SPM的使用是有很严格的规范的。

比如下列这样都是错误的


[plain] view plain copy print?
  1. Package.swift  
  2. Source:  
  3.      main.swift  
  4.      ModuleA:  
  5.            ClassA.swift  
  6. Test:  
  7.   
  8. Package.swift  
  9. Source:  
  10.      main.swift  
  11.      ClassA.swift  
  12. Test:  
  13. Package.swift  
  14. ModuleA:  
  15.      ClassA.swift  
  16. Source:  
  17.      main.swift  
  18. Test:  
Package.swift
Source:
     main.swift
     ModuleA:
           ClassA.swift
Test:

Package.swift
Source:
     main.swift
     ClassA.swift
Test:
Package.swift
ModuleA:
     ClassA.swift
Source:
     main.swift
Test:

在build时会出现

error: the package has an unsupported layout, unexpected source file(s) found:....

fix: move the file(s) inside a module


正确的目录结构应该是这样的

[plain] view plain copy print?
  1. Package.swift  
  2. Source:  
  3.      ModuleA:  
  4.           main.swift  
  5.      ModuleC:  
  6.           C.swift  
  7. Test:  
Package.swift
Source:
     ModuleA:
          main.swift
     ModuleC:
          C.swift
Test:


在source文件夹中,需要把项目代码以模块的方式划分,这样就能正常使用SPM了,然后在build一下


[plain] view plain copy print?
  1. swift build  
swift build


然后终端上就会显示



Compile Swift Module 'ModuleC' (2 sources)

Compile Swift Module 'ModuleA' (1 sources)

Linking ./.build/debug/ModuleA



说明ModuleA和ModuleC都已经构建好了,然后输入


swift package generate-xcodeproj


就可以使用Xcode编写代码了。当你打开Xcode的时候,你会发现,在左侧目录下方生成了ModuleC.framework,接着需要 General中添加这个库,然后可以在ModuleA中使用。在使用过程中,可能会出现 initializer is inaccessible due to ‘internal’ protection level的错误,这是因为ModuleC中的文件没有init方法,只要写一个init方法,就不会报这个错误,可以正常编写代码了




如果在build时遇到这类问题,是因为在build时,你自己创建的库之间没有建立依赖关系,这就需要在Package.swift文件中添加Target,来关联本地依赖

[plain] view plain copy print?
  1. import PackageDescription  
  2. let package = Package(  
  3.     name: "project name",  
  4.     targets: [  
  5.         Target(name: "ModuleA", dependencies: ["ModuleC"])  
  6.     ]  
  7. )  
import PackageDescription
let package = Package(
    name: "project name",
    targets: [
        Target(name: "ModuleA", dependencies: ["ModuleC"])
    ]
)



参考:

https://swift.org/package-manager/#example-usage



[plain] view plain copy print?
  1. <pre code_snippet_id="2343000" snippet_file_name="blog_20170419_3_3074708"></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <pre></pre>  
  6. <pre></pre>  
  7. <pre></pre>  
  8.