alibaba / handyjson Goto Github PK
View Code? Open in Web Editor NEWA handy swift json-object serialization/deserialization library
License: Other
A handy swift json-object serialization/deserialization library
License: Other
I want to use it in server side, can this project support Linux?
因为项目的原因,我还在用 HandyJSON 2.x ,表示非常好用,感谢作者。
但在使用当中发现一个问题,如果键值项有换行符,(输入项里面输入回车,这个是很常见的),_serializeToJSON
后生成的json 字符串是错的。
因为正确的 json 键值中如果有换行符,键值应该是 \\n
也就是字符 \
和 字符n
, 但, _serializeToJSON
后生成的json 是一个换行符\n
所以我做了以下修改, 不知道我理解得对不对。请大家指正
static func formatString(object: Any) -> String {
var string = String(object)
string = string.stringByReplacingOccurrencesOfString("\r", withString: "\\r")
string = string.stringByReplacingOccurrencesOfString("\n", withString: "\\n")
string = string.stringByReplacingOccurrencesOfString("\t", withString: "\\t")
return string
}
static func _serializeToJSON(object: Any) -> String {
if (object.dynamicType is String.Type || object.dynamicType is NSString.Type ) {
let json = "\"" + formatString(object) + "\""
return json
} else if (object.dynamicType is BasePropertyProtocol.Type) {
let json = formatString(object) ?? "null"
return json
}
var json = String()
let mirror = Mirror(reflecting: object)
if mirror.displayStyle == .Class || mirror.displayStyle == .Struct {
var handledValue = String()
var children = [(label: String?, value: Any)]()
let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children)!
children += mirrorChildrenCollection
var currentMirror = mirror
while let superclassChildren = currentMirror.superclassMirror()?.children {
let randomCollection = AnyRandomAccessCollection(superclassChildren)!
children += randomCollection
currentMirror = currentMirror.superclassMirror()!
}
children.enumerate().forEach({ (index, element) in
handledValue = _serializeToJSON(element.value)
json += "\"\(element.label ?? "")\":\(handledValue)" + (index < children.count-1 ? "," : "")
})
return "{" + json + "}"
} else if mirror.displayStyle == .Enum {
return "\"" + formatString(object) + "\""
} else if mirror.displayStyle == .Optional {
if mirror.children.count != 0 {
let (_, some) = mirror.children.first!
return _serializeToJSON(some)
} else {
return "null"
}
} else if mirror.displayStyle == .Collection || mirror.displayStyle == .Set {
json = "["
let count = mirror.children.count
mirror.children.enumerate().forEach({ (index, element) in
let transformValue = _serializeToJSON(element.value)
json += transformValue
json += (index < count-1 ? "," : "")
})
json += "]"
return json
} else if mirror.displayStyle == .Dictionary {
json += "{"
mirror.children.enumerate().forEach({ (index, element) in
let _mirror = Mirror(reflecting: element.value)
_mirror.children.enumerate().forEach({ (_index, _element) in
if _index == 0 {
json += _serializeToJSON(_element.value) + ":"
} else {
json += _serializeToJSON(_element.value)
json += (index < mirror.children.count-1 ? "," : "")
}
})
})
json += "}"
return json
} else {
return formatString(object) != "nil" ? "\"\(object)\"" : "null"
}
}
当类型中存在Date类型的字段时, 序列化失败
并且当json字符串中含有Date类型的字段时, 反序列化为对象后, 对象内的Date类型也是nil
请查看一下代码:
import UIKit
import HandyJSON
class Temp: HandyJSON {
var name:String?
var date:Date?
required init(){
name = "df"
date = Date.init(timeIntervalSinceNow: 0)
}
}
let json = Temp().toJSONString()
let r = JSONDeserializer<Temp>.deserializeFrom(json: json)
print(json)
print(r?.name)
print(r?.date)
看到alibaba又出了一款json序列化的框架
全国人民发来贺电,表示非常感谢.
Array 这样得出来的json 是使用不了的 都变成了[Any?,...] 了...类型丢了.但是打印出来的json是正常的
经过反复的测试了,使用版本1.2.1
JSON中为Int型,model中为字符串型 无法完成转换
如果我定义的属性 是自己开发需要 不需要字典转模型的属性 该怎么区分呢
public static func deserializeModelArrayFrom(json: String?) -> Array<T?>?
deserializeModelArrayFrom这个方法现在不能指定解析路径,对于这种情况如何处理?需要自己先定位JONS里面的数组?
pod search :
-> HandyJSON (0.1.0)
A Json Serialization & Deserialization Library for Swift
pod 'HandyJSON', '~> 0.1.0'
转换的值有可能是Array或者Dictionry类型,请问怎么声明类型能成功转换呢?
有时候服务端下发的id可能是Int也可能是String
很多时候客户端其实不关心这个类型,只是用于展示数据
对于JSON中的Int数据,反序列化时接收者如果是String能否自动做转化
我看code 好像并没有支持自动NSCoding,会支持吗?🙏
When I try to serialize a Date and some custom fields. Serializing a Date crashes, and I don't see how to provide a serialization mapper. Am I missing something or is it a missing feature?
Unable to find a specification for HandyJSON (~> 0.4.0)
class Knowledge : HandyJSON{
var title: String?
var desc: String?
var exercises:[Exercise]?
required init() {}
func mapping(mapper: HelpingMapper) {
// 指定 JSON中的`tests`字段映射到Model中的`exercises`字段
mapper.specify(property: &exercises, name: "tests")
}
}
在实际使用过程中,json字符串中的tests并没有映射到exercises,是我的用法不对么?
/Pods/HandyJSON/HandyJSON/Property.swift:404:86: Cannot assign to property: 'pointee' is a get-only property
json: {"body":""}
if let req = JSONDeserializer<T>.deserializeFrom(json: "{\"body\":\"\"}") {
print(req)
}
HandyJSON/Property.swift, line 164
当使用继承, 并在子类型中使用泛型时, 序列化失败
请在playground中运行以下代码:
import UIKit
import HandyJSON
class ResultBase: HandyJSON {
var message:String = "未知错误"
required init(){}
}
class ResultBase1<T>: ResultBase {
var obj:T?
}
var json = JSONDeserializer<ResultBase>.deserializeFrom(json: "{\"obj\":null,\"code\":0,\"message\":\"密码不正确!\",\"success\":false}")!
print(json.message) \\输出: 密码不正确
print()
json = JSONDeserializer<ResultBase1<String?>>.deserializeFrom(json: "{\"obj\":null,\"code\":0,\"message\":\"密码不正确!\",\"success\":false}")!
print(json.message) \\输出: 未知错误
print()
var result = ResultBase1<String?>()
result.message = "密码不正确"
var obj = JSONDeserializer<ResultBase1<String?>>.deserializeFrom(json: result.toJSONString())!
\\输出: Can not find offset info for property: message
print(obj.message) \\输出: 未知错误
Hello,
when sending my serialized object in my URLRequest with Alamofire,
my REST API didn't worked and the log said : "NSInvalidArgumentException [blah blah] JSON(write)".
I have used the toSimpleDictionary() func to send my json object.
I figured out that my object contained an enum and that when it is serialized the enum
is transforming into "MyModule.MyEnum.Value" instead of "Value".
To illustrate this clearly, see the class
class MyObject: HandyJSON {
var someInfo: String?
var myEnum: MyEnum?
required init() {}
}
see the enum
enum MyEnum: HandyJSONEnum {
case MyValue
case MyOtherValue
static func makeInitWrapper() -> InitWrapperProtocol? {
return InitWrapper<String>(rawInit: MyEnum.init)
}
}
see example of use
let myObject = MyObject()
request.someInfos = "some useful infos"
request.myEnum = MyEnum.MyValue
var urlRequest = URLRequest(url: "myURL")
urlRequest = try JSONEncoding.default.encode(urlRequest, with: myObject.toSimpleDictionary())
Alamofire.request(urlRequest)
My solution is to modify JSONSerializer.swift
extension GenericObjectTransformer {
static func transformToSimpleObject(object: Any) -> Any? {
// ...
case enum:
return String(describing: object) as Any
// ...
}
}
i'm aware that in this case, the result of your func will not be a pure "object"
but it will match my REST API regardless of the module name or enum name,
just the value is needed (a string in my case, i didn't try an int or something else).
What do you think ?
我们项目中的服务端使用nodejs编写,开发人员习惯用下划线命名比如result_code,有下划线并且都是小写,这就和swift的命名不一致,请问怎么处理?
json串是用HandyJSON产生的。
json串如下:
{"Height":"5.1181","Material":"Face: 100% cotton texture fabric with pearl stitching, 100% cotton texture fabric reverse","PrimaryColor":"Blue","ItemNo":"WR11-1133","RetailPrice":"15.39","SalesPrice":"15.39","SizeName":"Euro Sham","RetailItemInvLocRelation":"[Olliix.ItemInvLoc]","SizeDescription":"26"x26",","AllColors":"["Blue"]","Colors":"["Blue"]","Width":"6.1024","Product_ID":"4504","PicPath":"/Woolrich Lake side Euro silo.jpg","Description":"Blue cotton textured fabric with pearl stitching.","SetIncludes":"1 Euro Sham,","Qty":1,"CareInstructions":"MACHINE WASH COLD, GENTLE CYCLE, AND SEPARATELY. DO NOT BLEACH. TUMBLE DRY LOW, REMOVE PROMPTLY. DO NOT IRON. IF THERE IS NO FREE MOVEMENT IN THE WASHER OR DRYER, USE LARGE CAPACITY COMMERCIAL WASHER/DRYER.","AllSizes":"["Euro Sham"]","PrimarySize":"Euro Sham","Length":"9.8425","ProductName":"Lake Side Euro Sham","UPC":"675716504724","RetailBrandName":"Woolrich"}
prettify json string: {
"_id" : "582d633ef1a0b90950782205",
"authorId" : {
"nickname" : "p1别名",
"_id" : "582c549d0bd653ad5fb04336",
"username" : "p1",
"avatar" : "remote_default_user.png"
},
"commentIds" : [
],
"placeName" : "上海",
"content" : "testContent2",
"createdTime" : 1234567891,
"tag" : "art",
"relatedUserIds" : [
],
"image" : "1478704739.71422",
"loc" : [
121.456748,
31.262244
],
"read" : 0
}
after deserialization
authorId: nil
commentIds: nil
relatedUserIds: nil
how can i get the above three field back?
Thanks in advance!
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:60:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:67:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:74:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:60:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:67:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:74:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:60:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:67:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:74:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:60:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:67:82: warning: expression implicitly coerced from 'Any?' to Any
/Users/songlijun/Study/iOS/HandyJSONDemo/Carthage/Checkouts/HandyJSON/HandyJSON/JSONSerializer.swift:74:82: warning: expression implicitly coerced from 'Any?' to Any
为什么 里面的实现 都是 用 的 Object-C 的 NSDictionary. NSArray 而不是 swift 的 Collection 呢
似乎也没有 Array -> Model
我们通常会针对服务端下发的数字转化成枚举
enum ResourceType : Int {
case 新闻 = 1
case 自媒体 = 2
case 帖子 = 3
case 问答 = 4
case 话题 = 5
case Unknown = -1
}
在ObjectMapper里只要直接放上去这个,在用默认map就可以反序列化
初始化默认使用Unknown, 当服务端下发6,7等客户端无法识别的类型时还是会保存Unknown不变
HandyJSON能否实现类似效果,另外HandyJSON这个协议加到enum上会有入侵性
For a struct, if it has any designated initializer, compiler will complaint that:
type does not conform to protocol 'HandyJSON'.
For example, this struct can't pass compiler:
struct Animal: HandyJSON {
var name: String?
var id: String?
var num: Int?
init(name: String?, id: String?, num: Int?) {
self.name = name
self.id = id
self.num = num
}
}
I'm not quite sure if this is a bug.
按照 我对 Byte
的理解它应该是 UInt8
而不是 Int8
而且我修改成 UInt8 跑了下测试,也是没有问题的.
{
"artists": [
{
"name": "Pablo Picasso",
"bio": "Pablo Ruiz y Picasso (25 October 1881 – 8 April 1973), also known as Pablo Picasso, was a Spanish painter, sculptor, printmaker, ceramicist, stage designer, poet and playwright who spent most of his adult life in France.",
"image": "0",
"works": [
{
"title": "Guernica",
"image": "Picasso1",
"info": "Guern y violence and chaos."
},
{
"title": "The Weeping Woman",
"image": "Picasso2",
"info": "The Weeping Woman, Modern, London."
},
{
"title": "L'Homme aux cartes (Card Player)",
"image": "Picasso3",
"info": "1913–14, Museum of Modern Art, New York"
},
{
"title": "Asleep",
"image": "Picasso4",
"info": "The model of this painting, color blocks.(PabloPicasso.org)"
}
]
},
{
"name": "Rembrandt",
"bio": " Dutch history.",
"image": "6",
"works": [
{
"title": "Belshazzar's Feast",
"image": "Rembrandt1",
"info": " a painter of large, baroque history paintings."
},
{
"title": "The Night Watch",
"image": "Rembrandt2",
"info": "s collection."
},
{
"title": "Syndics of the Drapers' Guild",
"image": "Rembrandt3",
"info": "The Samplingrapers' Guild, is a 1662 oilportrait'."
},
{
"title": "Jacob de Gheyn III",
"image": "Rembrandt4",
"info": ", wearing similar clothing (ruffs and black doublets) and facing the opposite direction."
}
]
}
]
}
Is it possible to automatically do case-insensitive deserialisation?
例如 mapper.specify(property: &userName, name: "user.name")
在一些特殊的场景下,服务端下发的数据并不是严格按照JSON的格式的,比如JSON中某个String字段其实是一个JSON的字符串,在反序列化时我们势必要将其转化出来,有没有比较简便的方法
请问有json数组转模型数组的方法么?
当model中某个String变量,存的是json字符格式解析不出来
struct DemoStruct: HandyJSON {
var body: String = "{\"body\":\"123\"}"
var name: String = "name"
}
let requestStr = JSONSerializer.serializeToJSON(object: DemoStruct())
if requestStr != nil {
print(requestStr!)
}
if let req = JSONDeserializer<DemoStruct>.deserializeFrom(json: requestStr) {
print(req)
} else {
print("Error")
}
Optional/ImplicitUnwrappedOptional // T is one of the above types
So instead, one could do something like this...
let json = HandyJSON.toJSONString(myObject)!
Just for fun
CocoaPods
and Carthage
are awesome tools and make our life really easier, but there are some devs who still don't know how to use them.
It would be cool to add the Manual installation guide in your README.md
. You can take a look at my iOS Readme Template to see how you can do it.
序列化是否支持嵌套对象?怎么处理?
struct MHBanner: HandyJSON{
var type: String?
}
struct MHHomeDataModel : HandyJSON{
var banner: [MHBanner]?
}
这种怎么转,需要自己写扩展函数吗?
能不能写一个把model转换成字典或者数组的方法,有时候可能会用到.为什么类里面要实现这个required init() {}.
想知道什么时候支持swift package manager。
使用cocopods可以安装,但是手动安装失败,提示Use of unresolved identifier 'JSONSerialization'等错误,请问手动安装可以更简单点吗,感觉有点麻烦,谢谢
现在使用carthage安装成功了,谢谢了哈
用cocoapods加载的HandyJSON(1.2.1),swift 3.0, xcode 8.0, iOS 9.0;在“模拟机”的iPhone5上会提示
Undefined symbols for architecture i386:的错误
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.