跟进我之前的问题:
我设法使我的枚举符合 Codable 协议,实现了 init() 和encode(),它似乎可以工作。
enum UserState {
case LoggedIn(LoggedInState)
case LoggedOut(LoggedOutState)
}
enum LoggedInState: String {
case playing
case paused
case stopped
}
enum LoggedOutState: String {
case Unregistered
case Registered
}
extension UserState: Codable {
enum CodingKeys: String, CodingKey {
case loggedIn
case loggedOut
}
enum CodingError: Error {
case decoding(String)
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let loggedIn = try? values.decode(String.self, forKey: .loggedIn) {
self = .LoggedIn(LoggedInState(rawValue: …Run Code Online (Sandbox Code Playgroud) 我需要添加Codable两个类。一是CLLocationCoordinate2D,二是CLCircularRegion。
我对此没有任何问题CLLocationCoordinate2D,并且可以通过这样做来实现:
extension CLLocationCoordinate2D: Codable {
public enum CodingKeys: String, CodingKey {
case latitude
case longitude
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(latitude, forKey: .latitude)
try container.encode(longitude, forKey: .longitude)
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
latitude = try values.decode(Double.self, forKey: .latitude)
longitude = try values.decode(Double.self, forKey: .longitude)
}
}
Run Code Online (Sandbox Code Playgroud)
但我在尝试做同样的事情时遇到了很多问题CLCircularRegion。由于radius和center是只读属性,我无法真正以相同的方式创建它们。另一个问题是为什么我能够创建public …
所以,我有一个看起来像这样的类型:
struct Identifier {
let string: String
}
extension Identifier: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
string = try container.decode(String.self)
}
}
Run Code Online (Sandbox Code Playgroud)
这种类型的重点是如果我有如下所示的 JSON:
{
"identifier": "abc123",
// more properties ...
}
Run Code Online (Sandbox Code Playgroud)
...它将自动序列化为正确的类型,无需太多努力。Decodable但是,我在不创建包装类型的情况下对这种一致性进行单元测试时遇到了麻烦。
我想做的是这样的:
func testDecodableInit() {
let identifier = try! JSONDecoder().decode(Identifier.self, from: "1".data(using: .utf8)!)
XCTAssertEqual(identifier.string, "1")
}
Run Code Online (Sandbox Code Playgroud)
但显然这不起作用,因为"1"不是有效的 JSON。
是否可以在Decodable不创建包装类型并将数据更改为有效 JSON 的情况下为此一致性编写单元测试?
我正在尝试将我的数据映射到模型。我在其中使用 Firestore 快照侦听器来获取数据。在这里,我正在获取数据并映射到“用户”模型;
do{
let user = try User(dictionary: tempUserDic)
print("\(user.firstName)")
}
catch{
print("error occurred")
}
Run Code Online (Sandbox Code Playgroud)
这是我的模型:
struct User {
let firstName: String
// var lon: Double = 0.0
// var refresh:Int = 0
// var createdOn: Timestamp = Timestamp()
}
//Testing Codable
extension User: Codable {
init(dictionary: [String: Any]) throws {
self = try JSONDecoder().decode(User.self, from: JSONSerialization.data(withJSONObject: dictionary))
}
private enum CodingKeys: String, CodingKey {
case firstName = "firstName"
}
}
Run Code Online (Sandbox Code Playgroud)
如果我错了请纠正我。
崩溃是因为我在数据中获取“时间戳”。
从监听器获取的数据:
用户词典: …
如何将通过Swift 4 Codable协议编码的JSON对象写入文件?斯威夫特4以前我用过的JSONSerialization.writeJSONObject,但JSONSerialization.isValidJSONObject现在返回false所创建的数据(或字符串).一个例子:
import Foundation
class Shark : Codable
{
var name:String = ""
var carnivorous:Bool = true
var numOfTeeth:Int = 0
var hobbies:[String] = []
}
class JSON
{
class func encode<T:Encodable>(_ obj:T) -> String?
{
if let encodedData = try? JSONEncoder().encode(obj)
{
return String(data: encodedData, encoding: .utf8)
}
return nil
}
class func writeToStream(data:Any, path:String) -> Bool
{
var success = false
if JSONSerialization.isValidJSONObject(data)
{
if let stream = OutputStream(toFileAtPath: "\(path)", append: …Run Code Online (Sandbox Code Playgroud) 我正在编写一个程序,其中要分析JSON包括数组数组的数据,其中嵌套的数组具有不同的对象类型(特别是[[String,String,Int]])。例如,
{
"number": 5295,
"bets": [
[
"16",
"83",
9
],
[
"75",
"99",
4
],
[
"46",
"27",
5
]
]
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用可编码来帮助我解析数据,但是当我尝试类似
struct OrderBook: Codable {
let number: Int
let bets: [Bet]
}
struct Bet: Codable {
let price: String
let sale: String
let quantity: Int
}
Run Code Online (Sandbox Code Playgroud)
它给我错误说
预期对Dictionary进行解码,
<String, Any>但找到一个数组
我该如何解决?我不能声明一个空类型的数组。
在尝试使用基本JSONEncoder序列化float3对象数组时,发现float3不符合Codable协议,因此无法完成.
我尝试按照下面的编码和解码自定义类型的建议编写一个基本扩展,但是会'self' used before all stored properties are initialized在init中为每个赋值行呈现错误.我假设这是因为编译器不确定Float.self是否在float3初始化之前定义,但我不知道如何解决这个问题.
此外,init的结尾说Return from initializer without initializing all stored properties我假设除了x,y和z之外还有float3属性,但我想知道是否有办法默认/忽略这些,和/或如何找到完整除了挖掘simd中的所有float3扩展之外的属性列表.
如果您对如何做到这一点有任何想法,那么分享它们将非常感激.谢谢!
import SceneKit
extension float3: Codable {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
x = try values.decode(Float.self, forKey: .x)
y = try values.decode(Float.self, forKey: .y)
z = try values.decode(Float.self, forKey: .z)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(x, forKey: .x)
try …Run Code Online (Sandbox Code Playgroud) 我正在尝试为包含NSAttributedString的类实现Codable,但是在编译时出现错误:
try container.encode(str, forKey: .str)
Run Code Online (Sandbox Code Playgroud)
对成员'encode(_:forKey :)的错误含糊的引用
和
str = try container.decode(NSMutableAttributedString.self, forKey: .str)
Run Code Online (Sandbox Code Playgroud)
错误:没有任何“解码”候选者产生预期的上下文类型“ NSAttributedString”
我可以通过使用字符串中的NSData来解决它,但是我认为这应该可以工作
class Text : Codable {
var str : NSAttributedString
enum CodingKeys: String, CodingKey {
case str
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(str, forKey: .str). <-- error ambiguous reference to member 'encode(_:forKey:)'
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
str = try container.decode(NSMutableAttributedString.self, forKey: .str) <-- error: No 'decode' candidates …Run Code Online (Sandbox Code Playgroud) 如您所知,Codable是Swift 4中的新功能,因此我们将从模型的较早初始化过程转向这一点。通常我们使用以下方案
class LoginModal
{
let cashierType: NSNumber
let status: NSNumber
init(_ json: JSON)
{
let keys = Constants.LoginModal()
cashierType = json[keys.cashierType].number ?? 0
status = json[keys.status].number ?? 0
}
}
Run Code Online (Sandbox Code Playgroud)
在JSON cashierType键中可能会丢失,因此我们将默认值设置为0
现在,使用Codable做到这一点非常容易,如下所示
class LoginModal: Coadable
{
let cashierType: NSNumber
let status: NSNumber
}
Run Code Online (Sandbox Code Playgroud)
如上所述,键可能会丢失,但是我们不希望将Model Variables作为可选变量,因此我们如何使用Codable实现此目的。
谢谢
我在解码JSON结构时遇到问题,我无法对其进行更改以使其更易于解码(它来自firebase)。
如何将以下JSON解码为对象?问题是如何转换“ 7E7-M001”。这是带有抽屉的容器的名称。抽屉名称也用作键。
{
"7E7-M001" : {
"Drawer1" : {
"101" : {
"Partnumber" : "F101"
},
"102" : {
"Partnumber" : "F121"
}
}
},
"7E7-M002": {
"Drawer1": {
"201": {
"Partnumber": "F201"
},
"202": {
"Partnumber": "F221"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我必须在Container&Drawer类中解决哪些问题,才能将键作为title属性以及这些类中的对象数组?
class Container: Codable {
var title: String
var drawers: [Drawer]
}
class Drawer: Codable {
var title: String
var tools: [Tool]
}
class Tool: Codable {
var title: String
var partNumber: String
enum CodingKeys: String, CodingKey …Run Code Online (Sandbox Code Playgroud)