我正在尝试从API端点返回的数据呈现视图。我的JSON看起来(大致)如下:
{
"sections": [
{
"title": "Featured",
"section_layout_type": "featured_panels",
"section_items": [
{
"item_type": "foo",
"id": 3,
"title": "Bisbee1",
"audio_url": "http://example.com/foo1.mp3",
"feature_image_url" : "http://example.com/feature1.jpg"
},
{
"item_type": "bar",
"id": 4,
"title": "Mortar8",
"video_url": "http://example.com/video.mp4",
"director" : "John Smith",
"feature_image_url" : "http://example.com/feature2.jpg"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我有一个对象,表示如何在我的UI中布局视图。看起来像这样:
public struct ViewLayoutSection : Codable {
var title: String = ""
var sectionLayoutType: String
var sectionItems: [ViewLayoutSectionItemable] = []
}
Run Code Online (Sandbox Code Playgroud)
ViewLayoutSectionItemable 是一种协议,其中包括要在布局中使用的图像的标题和URL。
但是,sectionItems数组实际上由不同的类型组成。我想做的是将每个小节实例化为自己类的实例。
如何设置的init(from decoder: Decoder)方法,ViewLayoutSection以便让我遍历该JSON数组中的项目并在每种情况下创建适当的类的实例?
我正在尝试向我的本地服务器写一个POST请求,这是我的功能:
@IBAction func postButtonAction(_ sender: UIButton) {
guard let url = URL(string:"http://localhost:443/api/message") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
print("POSTED")
let date : Date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateTime = dateFormatter.string(from: date)
let newPost = MessageForPost(message: "Hi", timestamp: dateTime, latitude: "1.1", longitude: "2.2")
let newData = DataForPost(message: newPost)
let newPackage = PackageForPost(data: newData)
do {
let jsonBody = try JSONEncoder().encode(newPackage)
request.httpBody = jsonBody
print("jsonBody:",jsonBody)
let jsonBodyString = …Run Code Online (Sandbox Code Playgroud) 我会通过一些项目和消除JSON解析框架,因为它看起来很简单斯威夫特与4.做我以前遇到过这个地方古怪JSON回报Ints,并Dates作为返回Strings.
我看着GrokSwift的JSON解析斯威夫特4,苹果公司的网站上,但我没有看到任何跳出来回复:改变类型.
Apple的示例代码显示了如何更改密钥名称,但我很难弄清楚如何更改密钥类型.
这是它的样子:
{
"WaitTimes": [
{
"CheckpointIndex": "1",
"WaitTime": "1",
"Created_Datetime": "10/17/2017 6:57:29 PM"
},
{
"CheckpointIndex": "2",
"WaitTime": "6",
"Created_Datetime": "10/12/2017 12:28:47 PM"
},
{
"CheckpointIndex": "0",
"WaitTime": "8",
"Created_Datetime": "9/26/2017 5:04:42 AM"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我曾经习惯CodingKey将字典键重命名为符合Swift的条目,如下所示:
struct WaitTimeContainer: Codable {
let waitTimes: [WaitTime]
private enum CodingKeys: String, CodingKey {
case waitTimes = "WaitTimes"
}
struct WaitTime: Codable {
let checkpointIndex: String
let waitTime: …Run Code Online (Sandbox Code Playgroud) 是否可以将 Swift JSON 编码器配置为使用结构体属性的排序顺序作为 JSON 输出中字典键的排序顺序?默认情况下,它使用一些任意(但看似不是随机)的顺序,例如......
struct Example: Codable {
let id: Int
let name: String
let createdAt: Date
let comments: [String]
}
Run Code Online (Sandbox Code Playgroud)
... 结果是 ...
"example" : {
"id" : 1,
"name" : "Test",
"comments" : [
"Comment 1",
"Comment 2"
],
"createdAt" : 549539643.25327206
}
Run Code Online (Sandbox Code Playgroud)
我知道从语义上来说顺序并不重要,但我想保留它以用于调试目的。
我正在尝试在保存a的内容时优化存储空间NSTextView,即其NSTextStorage属性本身a NSAttributedString.
将其保存为Data,例如使用该rtfd(from:documentAttributes:)方法,并作为Codable结构的一部分,会产生非常大的字符串,比内容本身大得多,尤其是在将图像插入到内容中时NSTextView.例如,插入200K图像将生成5MB的JSON文件.
旁注:当Data对象直接编码而不是编码对象的属性时更糟糕,因为它是以小整数数组的形式编码而不是任意字符串.我不知道为什么,虽然我能够通过插入Data一个简单的包装结构来防止这种情况.
奇怪的是,使用ZIP压缩实际的JSON文件仍然会产生4MB的文件,只有20%的增益,因此我不清楚200K图像如何变成如此庞大,难以压缩的编码字符串.
我想弄清楚NSAttributedString使用Codable协议有效存储的正确方法是什么.非常感谢任何提示或建议.
我也想知道是否有一个有效的二进制编码选项Codable.
我有一个带有 2 个符合它的结构的 Animal 协议和一个存储动物列表的 Farm 结构。然后,我让它们都符合 Codable 将其存储在一个文件中,但它抛出了错误cannot automatically synthesize 'Encodable' because '[Animal]' does not conform to 'Encodable'
我明白为什么会发生这种情况,但我找不到好的解决方案。我怎样才能让数组只接受 Codable 和 Animal,而不将 Animal 标记为 Codable 所以这个问题不会发生,比如var animals = [Codable & Animal]?(或任何其他变通方法)。谢谢
protocol Animal: Codable {
var name: String { get set }
var sound: String { get set }
}
struct Cow: Animal {
var name = "Cow"
var sound = "Moo!"
}
struct Duck: Animal {
var name = "Duck"
var sound = "Quack!"
} …Run Code Online (Sandbox Code Playgroud) 我现在正在运行 Codables。但 API 有一些字符串条目,如果它们为空,有时可能会出现Int值。0我在这里搜索并发现了这个:Swift 4 Codable - Bool or String Values但我无法让它运行
我的结构
struct check : Codable {
let test : Int
let rating : String?
}
Run Code Online (Sandbox Code Playgroud)
评级大多数时候是这样的"1Star"。但如果没有评级,我会0以 Int 的身份返回。
我正在这样解析数据:
enum Result<Value> {
case success(Value)
case failure(Error)
}
func checkStar(for userId: Int, completion: ((Result<check>) -> Void)?) {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "xyz.com"
urlComponents.path = "/api/stars"
let userIdItem = URLQueryItem(name: "userId", value: "\(userId)")
urlComponents.queryItems = [userIdItem] …Run Code Online (Sandbox Code Playgroud) 我已经看到有关如何在所有案例都有关联值时使枚举符合 Codable 的答案,但我不清楚如何混合具有和不具有关联值的案例的枚举:
???如何在给定情况下使用相同密钥的多个变体?
???如何编码/解码没有关联值的案例?
enum EmployeeClassification : Codable, Equatable {
case aaa
case bbb
case ccc(Int) // (year)
init?(rawValue: String?) {
guard let val = rawValue?.lowercased() else {
return nil
}
switch val {
case "aaa", "a":
self = .aaa
case "bbb":
self = .bbb
case "ccc":
self = .ccc(0)
default: return nil
}
}
// Codable
private enum CodingKeys: String, CodingKey {
case aaa // ??? how can I accept "aaa", "AAA", and "a"?
case bbb
case ccc …Run Code Online (Sandbox Code Playgroud) 编译正常,没有问题:
class User: Codable {
let name: String
let email: String
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们有一个不由 CodingKey 表示的属性,则它需要一个初始值设定项:
class User: Codable { // Class 'User' has no initializers
let name: String
let email: String
private enum CodingKeys: String, CodingKey {
case name = "username"
}
}
Run Code Online (Sandbox Code Playgroud)
为什么它认为问题是缺乏合成初始化器,而不是需要 CodingKey 的警告或错误?为什么这违反了 Decodable 的一致性?
编辑:由于有些人似乎很困惑,我不是问如何解决该错误。这是显而易见的。我问的是,当您没有为所需属性指定 CodingKey 时,Codable 协议中会发生什么。
我正在尝试在 Swift 5.7 中创建一个Codable结构体[any Protocol]
struct Account: Codable {
var id: String
var name: String
var wallets: [any Wallet]
}
protocol Wallet: Codable {
var id: String { get set }
//... other codable properties
}
Run Code Online (Sandbox Code Playgroud)
但是,即使Wallet符合Codable
类型“帐户”不符合协议“可解码”
类型“帐户”不符合协议“可编码”
是否可以做出any符合Codable?
或者 Swift 5.7 仍然无法做到这一点?
编辑:正如回答的那样,您必须实现自己的一致性。这就是我的做法:
protocol Wallet: Identifiable, Codable {
var id: String { get set }
}
struct DigitalWallet: Wallet {
var id: String
// other properties …Run Code Online (Sandbox Code Playgroud)