pircate / cleanjson Goto Github PK
View Code? Open in Web Editor NEWSwift JSON decoder for Codable
License: MIT License
Swift JSON decoder for Codable
License: MIT License
class TesModel: NSObject, Codable {
var str: String?
var subMod: TesSubModel?
}
class TesSubModel: NSObject, Codable {
var str: String?
}
如果str、subModel不存在,或者类型不对,在解析后,
str = “”
subMod = TesSubModel()
因为model已经定义成可选型,而不是具体类型,此时如果返回的确定类型,而不是nil会感觉很奇怪,使用上也不方便,
比如要判断model是否存在,去做对应处理,应该是
if let model = subMod {
xxx
}
但是因为返回了确定类型,只是里面没值,就需要在做附加判断处理,比如
if let model = subMod, !model.str.isEmpty {
xxx
}
定义成可选型后,model解析异常是可以返回nil,或者可以选择可以返回nil 还是确定型
In order to achieve the project no invasion,Over the years I have been looking for native JSON processing scheme,until find here。
I based on "Codable" encapsulates a set of treatment scheme,and hope more communication
么有Podfile文件.
From Apple docs:
Starting in spring 2024, you must include the privacy manifest for any SDK listed below when you submit new apps in App Store Connect that include those SDKs, or when you submit an app update that adds one of the listed SDKs as part of the update. Signatures are also required in these cases where the listed SDKs are used as binary dependencies.
Could you please add a privacy manifest for this library? See the following URLs for additional information:
https://developer.apple.com/news/?id=r1henawx
https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
如果json返回来的是个数组怎么整?才开始用swift,希望多多指导
This code makes the exception:
let str = "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
let data = str.data(using: .utf8)!
let decoder = CleanJSONDecoder()
do {
let value = try decoder.decode(Double.self, from: data)
print("OK = \(value)")
} catch {
print("Error = \(error)")
}
If you remove one of zeroes in "str" then the decoding will be OK. So the limit is 1e165, after which the decoding fails regardless of Double type can really fit.
struct CustomAdapterAAA: JSONAdapter {
public func adapt(_ decoder: CleanDecoder) throws -> String {
return "default string"
}
}
这个方法可以给这个decoder解析出来的所有string设置默认值,想问下,可以给key设置单独的默认值么,比如说一个model里有strA,想要默认值是“strA”
strB,想要默认值是“strB”
支持这样单独设置默认值么?
数据源是Int类型 我用String接收 为什么会是nil
private func decodeIfNeeded<T : Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
if let objectValue = try? JSONDecoder().decode(type, from: "{}".data(using: .utf8)!) {
return objectValue
} else if let arrayValue = try? JSONDecoder().decode(type, from: "[]".data(using: .utf8)!) {
return arrayValue
} else if let stringValue = try decode(String.self, forKey: key) as? T {
return stringValue
} else if let boolValue = try decode(Bool.self, forKey: key) as? T {
return boolValue
} else if let intValue = try decode(Int.self, forKey: key) as? T {
return intValue
} else if let uintValue = try decode(UInt.self, forKey: key) as? T {
return uintValue
} else if let doubleValue = try decode(Double.self, forKey: key) as? T {
return doubleValue
} else if let floatValue = try decode(Float.self, forKey: key) as? T {
return floatValue
}
let context = DecodingError.Context(codingPath: [key], debugDescription: "Key: <\(key.stringValue)> cannot be decoded")
throw DecodingError.dataCorrupted(context)
}
你好,这个方法抛出异常了,抛出异常还是会中断解析吧?
enum RankListType: String, Codable {
case user = "USER"
case hall = "HALL"
}
let decoder = CleanJSONDecoder()
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
return Date()
})
上面的代码没有生效,看源码里面解析的时候用的是self.options.dateDecodingStrategy
,这个在库外面可以配置吗?
标准库 JSONDecoder 用 JSONParser 解析 json,性能提升了很多,希望有时间更新一下。
我用聚合笑话接口测试,他们返回的数据结构如下:
{
"reason":"Success",
"result":{
"data":[
{
"content":"某先生是地",
"hashId":"90B807CFEBF41",
"unixtime":1418745227,
"updatetime":"2014-12-16 23:53:47"
},
{
"content":"有一天我看",
"hashId":"206F5AC61F2A",
"unixtime":1418745227,
"updatetime":"2014-12-16 23:53:47"
}
]
}
}
下面是我创建的结构体
struct JuHeLaugh: Codable {
var error_code: Int
var reason: String
var result: ResultModel
struct ResultModel:Codable {
var data: [LaughItem]
}
}
struct LaughItem: Codable, Identifiable {
let id: UUID = UUID()
var content: String
}
请求代码
class Api {
func getLaughs(complete: @escaping ([LaughItem]) -> ()){
Alamofire.AF.request("http://v.juhe.cn/joke/content/list.php?sort=&page=&pagesize=&time=1418816972&key=4d9d1e5d2d284bc9e8e2428f43353f43")
.responseString { response in
guard let data = response.value else {
return
}
print(data)
do {
let decoder = CleanJSONDecoder()
let rst = try decoder.decode(JuHeLaugh.self, from: data.data(using:.utf8)!)
print(rst.result)
//complete(rst.result.data)
// This should work
} catch {
print("error is \(error.localizedDescription)")
}
}
}
}
本来这一切都没有问题,但是xcode会对LaughItem
有一个警告
Immutable property will not be decoded because it is declared with an initial value which cannot be overwritten
会提示我将LaughItem改成如下的样子
struct LaughItem: Codable, Identifiable {
var id: UUID
var content: String
}
但这样一改之后,decode就出问题了,错误日志:
error is The data couldn’t be read because it isn’t in the correct format.
尽管我添加了一个自定义的UidAdapter,也无济于事。
struct UidAdapter: JSONAdapter {
func adapt(_ decoder: CleanDecoder) throws -> UUID {
return UUID()
}
}
新的解码逻辑
do {
let decoder = CleanJSONDecoder()
decoder.valueNotFoundDecodingStrategy = .custom(UidAdapter())
let rst = try decoder.decode(JuHeLaugh.self, from: data.data(using:.utf8)!)
print(rst.result)
} catch {
print("error is \(error.localizedDescription)")
}
FATAL_SIGNAL SIGABRT fault_address:0x00000001ef024dd0
Thread 0 name: com.apple.main-thread
0libsystem_kernel.dylib
___abort_with_payload (in libsystem_kernel.dylib)
1libsystem_kernel.dylib
_abort_with_payload_wrapper_internal (in libsystem_kernel.dylib)
2libsystem_kernel.dylib
_abort_with_payload_wrapper_internal (in libsystem_kernel.dylib)
3libobjc.A.dylib
_objc_fatalv(unsigned long long, unsigned long long, char const*, char*) (in libobjc.A.dylib)
4libobjc.A.dylib
___objc_error (in libobjc.A.dylib)
5libobjc.A.dylib
_lookUpImpOrForward (in libobjc.A.dylib)
6libobjc.A.dylib
__objc_msgSend_uncached (in libobjc.A.dylib)
7libswiftCore.dylib
_swift_instantiateObjCClass (in libswiftCore.dylib)
8libswiftCore.dylib
_swift_initClassMetadataImpl(swift::TargetClassMetadataswift::InProcess, swift::ClassLayoutFlags, unsigned long, swift::TypeLayout const const*, unsigned long*, bool) (in libswiftCore.dylib)
9libswiftCore.dylib
type metadata completion function for _KeyedDecodingContainerBox (in libswiftCore.dylib)
10libswiftCore.dylib
swift::MetadataCacheEntryBase<(anonymous namespace)::GenericCacheEntry, void const*>::doInitialization(swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) (in libswiftCore.dylib)
11libswiftCore.dylib
_swift_getGenericMetadata (in libswiftCore.dylib)
12libswiftCore.dylib
KeyedDecodingContainer.init(A1) (in libswiftCore.dylib)
1 MyProj
_CleanJSONDecoder.container(keyedBy: A.Type) (in MyProj) CleanJSONDecoder.swift:75
1 MyProj
protocol witness for Decoder.container(keyedBy: A1.Type) in conformance CleanJSONDecoder (in MyProj) :0
15libswiftCore.dylib
dispatch thunk of Decoder.container(keyedBy: A1.Type) (in libswiftCore.dylib)
1 MyProj
specialized GradeTab.init(from: Decoder) (in MyProj) :0
1 MyProj
protocol witness for Decodable.init(from: Decoder) in conformance GradeTab (in MyProj) :0
18libswiftCore.dylib
dispatch thunk of Decodable.init(from: Decoder) (in libswiftCore.dylib)
1 MyProj
CleanJSONDecoder.unbox(: Any, as: Decodable.Type) (in MyProj) CleanJSONDecoder+Unbox.swift:475
2 MyProj
CleanJSONDecoder.unbox(: Any, as: A.Type) (in MyProj) CleanJSONDecoder+Unbox.swift:454
2 MyProj
CleanJSONUnkeyedDecodingContainer.decode(A.Type) (in MyProj) CleanJSONUnkeyedDecodingContainer.swift:411
2 MyProj
protocol witness for UnkeyedDecodingContainer.decode(A1.Type) in conformance CleanJSONUnkeyedDecodingContainer (in MyProj) :0
23libswiftCore.dylib
Array.init(from: Decoder) (in libswiftCore.dylib)
24libswiftCore.dylib
protocol witness for Decodable.init(from: Decoder) in conformance [A] (in libswiftCore.dylib)
25libswiftCore.dylib
protocol witness for Decodable.init(from: Decoder) in conformance [A] (in libswiftCore.dylib)
26libswiftCore.dylib
dispatch thunk of Decodable.init(from: Decoder) (in libswiftCore.dylib)
2 MyProj
CleanJSONDecoder.unbox(: Any, as: Decodable.Type) (in MyProj) CleanJSONDecoder+Unbox.swift:475
2 MyProj
CleanJSONDecoder.unbox(: Any, as: A.Type) (in MyProj) CleanJSONDecoder+Unbox.swift:454
2 MyProj
decodeObject #1 (from: CleanJSONDecoder) in CleanJSONKeyedDecodingContainer.decodeIfPresent(: A1.Type, forKey: A) (in MyProj) CleanJSONKeyedDecodingContainer.swift:886
3 MyProj
protocol witness for KeyedDecodingContainerProtocol.decodeIfPresent(: A1.Type, forKey: A.Key) in conformance CleanJSONKeyedDecodingContainer (in MyProj) :870
31libswiftCore.dylib
KeyedDecodingContainerBox.decodeIfPresent(: A1.Type, forKey: A.Key) (in libswiftCore.dylib)
32libswiftCore.dylib
KeyedDecodingContainer.decodeIfPresent(: A1.Type, forKey: A) (in libswiftCore.dylib)
3 MyProj
specialized PARespCourseSelectTabsConfigModel.init(from: Decoder) (in MyProj) :0
3 MyProj
protocol witness for Decodable.init(from: Decoder) in conformance PARespCourseSelectTabsConfigModel (in MyProj) :0
35libswiftCore.dylib
dispatch thunk of Decodable.init(from: Decoder) (in libswiftCore.dylib)
3 MyProj
CleanJSONDecoder.unbox(: Any, as: Decodable.Type) (in MyProj) CleanJSONDecoder+Unbox.swift:475
3 MyProj
CleanJSONDecoder.unbox(: Any, as: A.Type) (in MyProj) CleanJSONDecoder+Unbox.swift:454
3 MyProj
CleanJSONDecoder.decode(: A.Type, from: Any) (in MyProj) CleanJSONDecoder.swift:113
3 MyProj
CleanJSONDecoder.decode(: A.Type, from: JSONContainerConvertible) (in MyProj) CleanJSONDecoder.swift:101
4 MyProj
xxxStruct.transModel(: A.Type, withKeyValues: [String : Any]) (in MyProj) xxx.swift:208
比如说有些时候,需要把接口数据本地化:把模型数组转成字符串存到本地文件或数据库中
您原来的文档404了,可否在此回复下?
class father: Codable {
var id: String
var newsID: String
var title: String
var content: String
var section: String
var cat: String
var publishDatetime: String
var layout: String
private enum CodingKeys: String, CodingKey {
case id
case newsID
case title
case content
case section
case cat
case publishDatetime = "publish_datetime"
case layout
}
}
class son: father {
var landingType: String
var landingUrl: String
var cover: String
var pos: String
var listPos: String
var image: String
private enum CodingKeys: String, CodingKey {
case landingType = "landing_type"
case landingUrl = "landing_url"
case cover
case pos
case listPos = "list_pos"
case image
}
}
json
{"data":[{"id":"49","landing_type":"2","landing_url":"http:\/\/hlapp.stheadline.com\/ads_view\/49","title":"test inhouse","content":null,"cover":"49","pos":"2","list_pos":"4","image":null,"layout":"3"},{"id":"47","landing_type":"1","landing_url":"http:\/\/192.168.148.244\/headline_app_back_end\/Ads\/form","title":null,"content":null,"cover":"47","pos":"1","list_pos":"2","image":"hl_app_ads\/2019\/05\/22\/20190522104030_9444.jpg","layout":"1"}],"result":1}
子类中除了父类包含的属性,其他属性都没法赋值
{
key: [{newName: "jack"}]
}
如果我想把newName 映射成name,我该怎么写呢?
struct CleanJSONModel: Codable {
var name: String?
}
if model.name == nil {
debugPrint("没有name")
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.