TriforkSwiftNetworking

安装

支持 Swift Package Manager。

用法

在这里我们尝试创建一个用于博客 API 的简单例子。

首先我们需要创建一个模型。

public struct Post: Codable {
    let id: UUID
    let title: String
    let body: String
}

然后我们创建一个 CollectionResponse,因为我们想要检索 Post 列表。

public struct PostsResponse: CollectionResponse {
     public typealias OutputType = Post

    public var data: [OutputType]

    public init(input: Data, response: HTTPURLResponse?) throws {
        let decoder = JSONDecoder()

        data = try decoder.decode([Post].self, from: input)
    }
}

最后我们创建 RequestHTTPRequest 实现了大部分变量作为默认值。唯一需要提供的是 url

public struct PostsRequest: HTTPRequest {
    public typealias ResponseType = PostsResponse

    public var url: String { "https://myblog/api/posts" }
    public var query: [String : String]? {
        ["category": category]
    }

    private let category: String

    init(category: String) {
        self.catgory = category
    }
}

为了创建一个新的请求,从 UIViewController 等,我们可以看看下面的例子

final class PostsController: UIViewController {
    let networkSession: NetworkSession = URLSession.shared

    var posts = [Post]()

    var anyCancellables = [AnyCancellable]()

    func viewDidLoad() {
        super.viewDidLoad()

        let postsRequest = PostsRequest(category: "dogs")

        networkSession.dataTaskPublisher(for: postsRequest)
            .sink { Error in
                // Handle error
            } receiveValue: { response in
                self.posts = response.data
            }
            .store(in: &anyCancellables)
    }
}

viewDidLoad 中,我们开始创建请求,然后我们使用 NetworkSession 获取它。
然后我们就像平常一样使用 Combine 框架处理它。

TSNMockHelpers

该包包含一个 TSNMockHelpers 框架,它允许你在进行单元测试时模拟 URLSession

import TriforkSwiftNetworking
import TSNMockHelpers

let baseUrl = "http://example.com"

let request = TestRequest(
    baseUrl: baseUrl,
    pathComponents: ["test", "mock"],
    method: .get,
    query: nil,
    body: nil,
    headers: nil,
    cachePolicy: .useProtocolCachePolicy
)

let url = URL(string: "\(baseUrl)/test/mock")
URLSessionStubResults.resultsForUrls[url] = .dataResponse(
    data: "MyData".data(using: .utf8)!,
    response: URLSessionStubResponses.response(url: url!)!
)

let expect = XCTestExpectation()
session.dataTask(with: request) { (data, response, error) in
    XCTAssertEqual("MyData", String(data: data!, encoding: .utf8))
    XCTAssertNil(error)
    XCTAssertEqual(200, (response as? HTTPURLResponse)?.statusCode)
    expect.fulfill()
}.resume()
wait(for: [expect], timeout: 1.0)