SwiftAPIClient 3.1.2

SwiftAPIClient 3.1.2

RichAppz Ltd 维护。



  • Rich Mucha

SwiftAPIClient-SDK

SwiftAPIClient 是一个网络层,能够快速实现服务器 API 调用。

框架通过在设备上存储您的 JSON 数据来包含离线能力,以便按需检索。以下是一些示例。

介绍

该框架的开发是为了加快开发和提高效率。在为简单的数据应用使用 CoreData/Realm 存储离线数据之后,发现需要减少对复杂数据存储的需求,并帮助减小应用程序包的大小。

功能

该项目经过长时间的构建并在许多项目中使用。

  • 项目使用了 Swift 的 Codable Protocols,并且所有模型都将符合 Codable。
  • 框架有一个机制可以获取用于 DEMO 和测试目的的 JSON 资源文件。
  • 有一个存储机制将数据响应存储到 UserDefaults、FileManager 或根本不存储,每个请求都是可配置的。有设置启用 SHA256 编码以确保存储的数据安全。
  • 框架中有一个机制可以监控网络状态,如果无连接,则所有调用都将路由到最后收到的调用,如果数据可用,则将其返回,这确保了框架可以离线开箱即用。
  • 该框架拥有一个全新的ClosureService,它可以处理调用重复的情况。如果应用在初始调用完成之前多次请求完全相同的调用,框架将停止进一步的调用,但会完成所有代码块。

听起来有很多东西要记住!所以已经设置了简单的辅助函数,它会为你的上述所有操作,这样你就不需要记住了。

支持

  • iOS 10.0+ / macOS 10.13+ / tvOS 10.0+ / watchOS 3.0+

要求

  • Xcode 11.0+
  • Swift 4.2+

安装

CocoaPods

CocoaPods是一个Cocoa项目的依赖管理器。有关使用和安装说明,请访问他们的网站。要使用CocoaPods将SwiftAPIClient集成到你的Xcode项目中,在你的Podfile中指定它

pod 'SwiftAPIClient'

注意:如果你想仍然使用与Alamofire的旧版本,请锁定你的Pod - 这不再支持

pod 'SwiftAPIClient', '2.1.3'

实现

import SwiftAPIClient

Swift Package Manager

Swift Package Manager 是一个用于自动分发 Swift 代码的工具,并集成到 swift 编译器中。

一旦你设置了你的 Swift 包,将 SwiftAPIClient 作为依赖项添加就像将其添加到 Package.swiftdependencies 值一样简单。

dependencies: [
    .package(url: "https://github.com/RichAppz/SwiftAPIClient-SDK.git", .upToNextMajor(from: "1.0.3"))
]

客户端

创建所需的网关需要客户端——您可以创建多个以连接到各种服务器和身份验证。

class ClientExample: Service {

    // ==========================================
    // MARK: Properties
    // ==========================================

    var rootURL = "<YOUR ENDPOINT>"
    var headers: [String: String] = [:]
    let networkQueue = OperationQueue()

    // ==========================================
    // MARK: Singleton
    // ==========================================

    static let shared = ClientExample()

    // ==========================================
    // MARK: Initialization
    // ==========================================

    init() { }

    // ==========================================
    // MARK: Helpers
    // ==========================================

    func post(_ request: Request, completion: OperationResponse? = nil) {
        makeRequest(.post, request: request, completion: completion)
    }

    func get(_ request: Request, completion: OperationResponse? = nil) {
        makeRequest(.get, request: request, completion: completion)
    }

    func delete(_ request: Request, completion: OperationResponse? = nil) {
        makeRequest(.delete, request: request, completion: completion)
    }

    func put(_ request: Request, completion: OperationResponse? = nil) {
        makeRequest(.put, request: request, completion: completion)
    }

    func patch(_ request: Request, completion: OperationResponse? = nil) {
        makeRequest(.patch, request: request, completion: completion)
    }

}

模型示例

CodeModule 已配置,可以帮助解析 JSON 数据。

DateDecodingStrategy - handling various date formats
enum DateType: String {
    case iso8601x = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
    case iso8601 = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
    case java = "yyyy-MM-dd'T'HH:mm:ss.sssZ"
    case javaSimple = "yyyy-MM-dd HH:mm:ss Z"
    case simple = "yyyy-MM-dd"
    
    static let formats: [DateType] = [iso8601x, iso8601, java, javaSimple, simple]
}
  • KeyDecodingStrategy - 处理包含蛇形混合大小写参数的端点,而不需要考虑这些。

使用 Model 泛型类使框架能够存储和检索您的模型。

public struct Movie: Model {

    public let title: String?
    public let year: Int?
    public let rated: String?
    public let genre: [String]?

    public init?(json: [String: Any]) {
        title = json["Title"] as? String
        year = json["Year"] as? Int
        rated = json["Rated"] as? String
        genre = json["Genre"] as? [String]
    }

    public static var storageIdentifier: String {
        return "movie"
    }

    public static var identifier: String {
        return "title"
    }

}

端点函数示例

extension Service {
    
    public func fetchMovieWith(query: String, completion: @escaping ((Movie?, Error?) -> Void)) {
        get(Request(
            parameters: ["t": query])
        ) { (response) in
            let movie: Movie? = try? StorageClient.map(object: response.data)
            DispatchQueue.main.async {
                completion(movie, response.error)
            }
        }
    }
    
}

数据检索示例

let account: Account? = try? StorageClient.retrieve()
let accounts: [Account]? = try? StorageClient.retrieve()

附加功能

简写

特性列表相当长,编写请求可能很耗时,所以请尝试使用那些已创建的扩展,允许您这样做

extension Service {

    public func fetchMovieWith(query: String, completion: @escaping ((Movie?, Error?) -> Void)) {
        stdGetRequest(
            RequestModel(
                params: ["t": query],
                storageType: .fileManager),
            completion: completion
        )
    }
    
}

如果您想使用 stdGetRequest、stdPostRequest 辅助函数(否则您可以创建自己的手动请求),则完成始终应遵循以下之一

((Model?, Error?) -> Void)?
(([Model]?, Error?) -> Void)?

stdGetRequest 具有多种可为您请求设置的属性(也适用于 POST)

endpoint - 您设置的枚举值 endpointParam - 需要放入端点的参数,例如 venues/%@ params - 需要随请求一起发送的 JSON 主体 storageType - 您可以在这里指定您想要的存储类型 storageAdditionKey - 这是您想注入到存储中的额外参数,以识别请求,例如场所的 id 或分页参数,使存储能够识别数据。 notification - 您设置的 Notification.Name completion - 直接传递完成块

所有参数都是可选的或具有默认值,您可以查看代码以了解此信息。

stdGetRequeststdPostRequest 都处理了上述所有功能,应使用手动路由之外的路由。

下载文件

如果您在 Request 中使用 operationType,将其值设置为 .fileDownload,然后如果下载了文件,您将得到一个临时文件存储 URL。

    get(
        Request(
            endpoint: "/your-filename.csv",
            operationType: .fileDownload,
            priority: .high,
            qualityOfService: .default)
    ) { (response) in
        DispatchQueue.main.async {
            completion(response.fileStoreUrl, response.error)
        }
    }

上传文件

要上传文件,请使用请求中可用的 FileUpload 模型,并包含一些必需项

public struct FileUpload {
    
    /// If you are converting images you can use `jpegData(compressionQuality: 0.5)`
    public let data: Data
    /// This is the parameter expected by your server
    public let paramName: String
    /// Needs to contain the file extension also eg `filename.png`
    public let fullFileName: String
    /// Standard mimeType string that is expected by HTTP Requests
    public let mimeType: String
    
}

示例

    put(
        Request(
            endpoint: "your-endpoint",
            upload: FileUpload(
                data: data,
                paramName: "file",
                fullFileName: "filename.jpg",
                mimeType: "image/jpg"
            ),
            priority: .high,
            qualityOfService: .default
        )
    ) { (response) in
        // Handle response
    }

许可(MIT)

版权所有 (c) 2017-2020 RichAppz Limited (https://richappz.com)

特此免费授予任何获得本软件及其相关文档副本(统称“软件”)的人士在不受限制的情况下使用、复制、修改、合并、出版、分发、再许可和/或销售软件副本的权利,并允许该软件提供的人士进行此类操作,但须遵守以下条件

上述版权声明和本许可声明应包含在软件的任何副本或主要部分中。

软件“按原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定用途和侵权保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是在合同行动、侵权或其他情况下,无论是在与软件或与使用或其它软件处置有关的软件之中。


Rich Mucha, RichAppz Limited [email protected]