Swift 4可解码协议如何处理包含密钥的字典,该密钥的名称在运行时才知道?例如:
[
{
"categoryName": "Trending",
"Trending": [
{
"category": "Trending",
"trailerPrice": "",
"isFavourit": null,
"isWatchlist": null
}
]
},
{
"categoryName": "Comedy",
"Comedy": [
{
"category": "Comedy",
"trailerPrice": "",
"isFavourit": null,
"isWatchlist": null
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
这里我们有一系列字典; 所述第一有键categoryName和Trending,而第二个有密钥categoryName和Comedy.categoryName键的值告诉我第二个键的名称.如何使用Decodable表达?
为什么我得到"类型'书签'不符合协议'可解码'"错误消息?
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
}
Run Code Online (Sandbox Code Playgroud)
我不希望保存出版物var,因为出版物拥有书签,但书签需要知道它属于哪个出版物.Publication的解码初始化将书签引用设置为自身.
我一直在玩,Codable并从文件中读取和写入JSON.现在我想写一个Coder可以读写iOS .strings文件的自定义.谁能帮我这个?我发现协议Encoder和Decoder,但我不知道我应该实现此:
class StringsEncoder {}
extension StringsEncoder: Encoder {
var codingPath: [CodingKey?] {
return []
}
var userInfo: [CodingUserInfoKey : Any] {
return [:]
}
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
}
func unkeyedContainer() -> UnkeyedEncodingContainer {
}
func singleValueContainer() -> SingleValueEncodingContainer {
}
}
extension StringsEncoder: Decoder {
func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey {
}
func unkeyedContainer() throws -> …Run Code Online (Sandbox Code Playgroud) 我Codable第一次使用Swift 4的协议,我无法理解使用decodeIfPresentfrom Decodable.
/// Decodes a value of the given type for the given key, if present.
///
/// This method returns `nil` if the container does not have a value associated with `key`, or if the value is null. The difference between these states can be distinguished with a `contains(_:)` call.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated …Run Code Online (Sandbox Code Playgroud) 我目前正在处理Codable项目中的类型并遇到问题.
struct Person: Codable
{
var id: Any
}
Run Code Online (Sandbox Code Playgroud)
id在上面的代码中可以是a String或an Int.这就是id类型的原因Any.
我知道Any不是Codable.
我需要知道的是我如何才能使它发挥作用.
在应用程序中,我们有两种类型的贴纸,字符串和位图。每个贴纸包可以包含这两种类型。这就是我声明模型的方式:
// Mark: - Models
protocol Sticker: Codable {
}
public struct StickerString: Sticker, Codable, Equatable {
let fontName: String
let character: String
}
public struct StickerBitmap: Sticker, Codable, Equatable {
let imageName: String
}
Run Code Online (Sandbox Code Playgroud)
在用户选择一些贴纸并使用它们后,我们希望将这些贴纸保存到其中,UserDefaults以便我们可以向他显示“最近使用过的”贴纸选项卡。我正在尝试解码保存的[Sticker]数组:
let recentStickers = try? JSONDecoder().decode([Sticker].self, from: data)
Run Code Online (Sandbox Code Playgroud)
但我收到以下编译错误:
Protocol type 'Sticker' cannot conform to 'Decodable' because only concrete types can conform to protocols
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我声明Stickeras Codablewhich 也实现了Decodable. 任何帮助将不胜感激!
我有一个通用的REST请求:
struct Request<T> {…}
Run Code Online (Sandbox Code Playgroud)
这T是请求的返回类型,例如:
struct Animal {…}
let animalRequest = Request<Animal>
let animal: Animal = sendRequest(animalRequest)
Run Code Online (Sandbox Code Playgroud)
现在我想表达泛型类型必须符合,Decodable以便我可以解码来自服务器的JSON响应:
struct Request<T> where T: Decodable {…}
struct Animal: Decodable {…}
Run Code Online (Sandbox Code Playgroud)
这是有道理和有效的 - 直到我得到一个没有响应的请求,a Request<Void>.编译器对此不满意:
Type 'Void' does not conform to protocol 'Decodable'
Run Code Online (Sandbox Code Playgroud)
我通过添加Decodable一致性来解决这个问题的错误尝试Void很快被编译器发现:
extension Void: Decodable {…} // Error: Non-nominal type 'Void' cannot be extended
Run Code Online (Sandbox Code Playgroud)
将请求通用于返回类型是正确的.有没有办法让它与Void返回类型一起使用?(例如,只在服务器上创建内容并且不返回任何内容的请求.)
我试图连接我的 API 数据以在单元格中查看它,但似乎我无法得到我的响应,而且总是== nil
下面的代码描述了 Country.SWIFT // Model.SWIFT // Response.SWIFT,它显示了如何我可以使用 Codable 获取 JSON 响应吗? CountryCell.SWIFT 展示了我如何使用它来调用 API API 图像的链接:

国家.SWIFT
struct Country: Decodable {
var CountryName = ""
var CountryImage = ""
var objectId = ""
// MARK: - Coding Keys
enum CodingKeys: String, CodingKey {
case CountryName = "CountryName"
case CountryImage = "CountryImage"
case objectId = "objectId"
}
//MARK: - Json Decoder
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Parsing our attributes
self.CountryName …Run Code Online (Sandbox Code Playgroud) 当符合Codable协议时,我不能轻易跳过非Codable类的可选属性
在Ride结构,我们要跳过的编码和解码的driver财产,只要把它nil解码时:
struct Ride: Codable {
public var number: String
public var passenger: Passenger? // Codable conforming
public var driver: Driver? // NSObject subclass, doesn't conform to Codable
enum CodingKeys: String, CodingKey {
case number
case passenger
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我得到一个编译错误
类型'驱动程序'不符合协议'可解码'
到目前为止,我提供的唯一解决方案是通过提供以下方法手动编码和解码:
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
number = try? values.decode(String.self, forKey: .number)
passenger = try? values.decode(Passenger.self, forKey: .passenger) …Run Code Online (Sandbox Code Playgroud) 我正在使用Swift 4和Xcode 9.2编写程序.我在编写可编码类(完全是类,而不是struct)时遇到了困难.当我尝试从另一个类继承一个类时,JSONEncoder不从子类(子)获取所有属性.请看这个:
class BasicData: Encodable {
let a: String
let b: String
init() {
a = "a"
b = "b"
}
}
class AdditionalData: BasicData {
let c: String
init(c: String) {
self.c = c
}
}
let encode = AdditionalData(c: "c")
do {
let data = try JSONEncoder().encode(encode)
let string = String(data: data, encoding: .utf8)
if let string = string {
print(string)
}
} catch {
}
Run Code Online (Sandbox Code Playgroud)
它会打印出来: {"a":"a","b":"b"}
但我需要这个: {"a":"a","b":"b","c":"c"}
它看起来像c类的属性AdditionalData只是失去了某处,不知何故.
所以问题是:如果我有使用协议编码的类Encodable如何正确地创建子类(此类的子类,继承)类?
我会感谢任何帮助或建议.