iOS开发-SwiftSwiftSwift好文收藏

Swift: SPM包管理器

2021-09-02  本文已影响0人  猪猪行天下

SPM:Swift Package Manager(swift包管理器),管理Swift代码分发的工具,用于处理模块代码的下载、编译和依赖关系。类似CocoaPods,不过比CocoaPods更简洁,代码的侵入性更小,也不需要额外安装工具。

SPM依赖安装

Xcode自带SPM,终端上可查看SPM版本:

$ swift package --version
Swift Package Manager - Swift 5.3.0

新建项目SPMTest,添加SPM依赖,File -> Swift Package -> Add Package Dependency...

add_spm.png

或者点击到 PROJECT -> Swift Packages 点击加号添加依赖

add_spm1.png

输入需要添加的第三方库的链接:

add_lab.png

点击next等待验证成功后直,根据自己的实际需要选择版本,如下图:

package_version.png

有三个选项:

添加完成之后,项目中会出现Swift Package Dependencies这样一个目录:

add_dependencies.png

这样就可以在项目中直接使用这个第三方依赖库了。

如果你要更新SPM中的依赖,选择 File -> Swift Packages -> Update to Latest Package Versions 即可。

如果想要修改某个第三方库的版本策略,可以双击第三方库即可出现修改面板进行相应的修改。

创建本地Swift Package库

我们新建一个Swift Package,打开我们上面用到的项目SPMTest后选择File->New->Swift package...,把这个包命名为ZZPackage,并添加到现有的项目中。

create_spm.png

新建完成后可以看到在项目工程中包含了ZZPackage这个Package,

show_zzjpackage.png

如何引入ZZPackage到工程中并使用其中的功能模块呢?

Targets ->General -> Frameworks..部分,点击+号,添加ZZPackage

link_package.png

到这里我们就把ZZPackage引入到我们的项目中了。在ZZPackage下的 Sources/ZZPackage 目录下新建ExView.swift,然后在工程中使用到这个文件中的方法:

import SwiftUI

extension View {
  //module对外的访问权限设为public
   public func printLog(_ value:Any) -> some View {
        #if DEBUG
        print(value)
        #endif
        return self
    }
    
}

直接编译报错了:

comp_error.png

可以看到要求iOS13及以上,因为我们加入的是swiftUI代码,所以需要在Package.swift中添加platforms: [.iOS(.v13)],或在扩展代码上面添加@available(iOS 13.0, *)

这两种方式编译都可以成功!

运行看下结果吧:

run_result.png

发布你的 Swift Package

找到SPMTest文件夹下的ZZPackage文件夹,上传库到云端(github, gitee 或者其他托管服务器)。
然后设置Tag版本号就可以了。删除本地Package,就可以通过仓库地址加载远程Package了。

SPM文件及配置

dep_config.png
// swift-tools-version:5.3

import PackageDescription

let package = Package(
    name: "ZZPackage",
    platforms: [.iOS(.v13)],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "ZZPackage",
            targets: ["ZZPackage"]),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.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 this package depends on.
        .target(
            name: "ZZPackage",
            dependencies: []),
        .testTarget(
            name: "ZZPackageTests",
            dependencies: ["ZZPackage"]),
    ]
)

第一行始终是Swift Tools的版本,这里是swift5.3版本。这行注释说明了构建swift package所需最低的swift版本号。然后我们导入了PackageDescription,这个库提供了我们需要配置swift package所需的API。

resources 添加资源文件

.target下,我们可以添加资源文件字段resources,例如添加图片资源自定义文件夹imgs

resources_imgs.png

如果资源或路径添加不对,编译报错!

对于resources属性,有两个静态方法: process()copy()

    //调用举例
    public func bgImg() -> some View {

        let path = Bundle.module.path(forResource: "imgs/wechat@2x.png", ofType: nil)
        
        guard let uiimage = UIImage.init(contentsOfFile:path!) else {
            fatalError("image load path error: \(path as Any)")
        }
        let img = Image(uiImage: uiimage)
        return self
            .background(img)
        
    }

.target下,我们可以添加资源文件字段resources,使用默认文件夹Resources,推荐使用这种:

resources.png

这种方式可以直接在process中指定文件夹Resources,使用的时候也无需引用该路径。swift在编译的时候不会添加Resources路径。

    public func bgImgUrl() -> some View {
        
        let path = Bundle.module.url(forResource: "wechat@2x", withExtension: "png")
        guard let data = try? Data(contentsOf: path!),
              let uiimage = UIImage.init(data: data)
        else {
            fatalError("image load path error: \(path as Any)")
        }
        let img = Image(uiImage: uiimage)
        return self
            .background(img)
        
    }

这里也有一个第三方使用resources的案例:

NutritionFacts.png

Assets.xcassets中添加的图片资源不需要使用路径方式,使用方式如下:

Image("imageName", bundle: .module)

SPM不支持混合语言开发,在同一个target中无法使用多语言,否则编译报错。

如何实现混合

可参考这个文章

这里是个Swift和OC混编的示例,每种语言一个target,单个target内不可使用多语言:

spm_objc.png

对外导出的.h头文件,默认放在include文件中。如果要自定义导出文件需要设置publicHeadersPath导出的公共头文件夹路径。这里我们把原来的include文件名改为header,如下所示:

custom_path.png

然后把这个OC的包添加依赖到需要使用的Swift的包里,就可以正常使用了!!

上一篇下一篇

猜你喜欢

热点阅读