问题
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