Generic Decoders in Swift 4

萝らか妹 提交于 2019-12-11 06:34:52

问题


Currently I'm using this code to handle decoding some data:

private func parseJSON(_ data: Data) throws -> [ParsedType] 
{
    let decoder = JSONDecoder()
    let parsed = try decoder.decode([ParsedType].self, from: data)
    return parsed
}

private func parsePlist(_ data: Data) throws -> [ParsedType] 
{
    let decoder = PropertyListDecoder()
    let parsed = try decoder.decode([ParsedType].self, from: data)
    return parsed
}

Is there a way to create a generic method that ties all this repeated code together?

private func parse(_ data: Data, using decoder: /*Something*/) throws -> [ParsedType]
{
    let parsed = try decoder.decode([ParsedType].self, from: data)
    return parsed
}

回答1:


If you look at the swift stdlib for JSONEncoder and PropertyListDecoder you will see that they both share a method

func decode<T: Decodable >(_ type: T.Type, from data: Data) throws -> T

So you could create a protocol that has said method and conform both decoders to it:

protocol DecoderType {
    func decode<T: Decodable >(_ type: T.Type, from data: Data) throws -> T
}

extension JSONDecoder: DecoderType { }
extension PropertyListDecoder: DecoderType { }

And create your generic parse function like so:

func parseData(_ data: Data, with decoder: DecoderType) throws ->  [ParsedType] {
    return try decoder.decode([ParsedType].self, from: data)
}



回答2:


Decodable+Generic.swift

import Foundation

// Generic decode method for Decodable
func decode<T: Decodable>(data: Data) throws -> T {
    let decoder = JSONDecoder()
    return try decoder.decode(T.self, from: data)
}

Decodable+GenericTests.swift

import XCTest
@testable import YourProject

class Decodable_EncodableTests: XCTestCase {
    func testDecodableEncodable() {
        struct User: Decodable, Encodable {
            let name: String
            let sex: String
        }
        let json = """
        {
            "name": "Ronaldo",
            "sex": "Female"
        }
        """.data(using: .utf8)!

        do {
            // When
            let name = "Ronaldo"
            let sex = "Female"
            let user: User = try decode(data: json)

            // Then
            XCTAssertEqual(user.name, name)
            XCTAssertEqual(user.sex, sex)

        } catch let error {
            XCTFail(error.localizedDescription)
        }
    }
}


来源:https://stackoverflow.com/questions/49275745/generic-decoders-in-swift-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!