ikesyo / himotoki Goto Github PK
View Code? Open in Web Editor NEWA type-safe JSON decoding library purely written in Swift
License: MIT License
A type-safe JSON decoding library purely written in Swift
License: MIT License
[!] Unable to satisfy the following requirements:
- `Himotoki (~> 3.1)` required by `Podfile`
- `Himotoki (~> 3.1)` required by `Podfile`
- `Himotoki (~> 3.1)` required by `Podfile`
None of your spec sources contain a spec satisfying the dependency: `Himotoki (~> 3.1)`.
You have either:
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
My Podfile
platform :ios, '10.0'
abstract_target 'dependencies' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'Moya/RxSwift'
pod 'Himotoki', '~> 3.1'
pod 'RxSwift', '~> 3.1'
pod 'RxCocoa', '~> 3.1'
pod 'SwiftDate', '~> 4.0'
pod 'RealmSwift', '~> 2.8'
pod 'RxDataSources', '~> 1.0'
pod 'SVProgressHUD'
pod 'Firebase/Core'
pod 'Firebase/Messaging'
end
Do you have any idea for applying transform function?
struct User: Decodable {
let createdAt: NSDate?
static func decode(e: Extractor) -> User? {
return build(
e <|? "createdAt" <^> NSDate.dateFromUTCString
).map(create)
}
}
decodeValue
reports the wrong keyPath.
The TypeMismatch
error below should be like this
TypeMismatch(expected: Int, actual: String, keyPath: KeyPath(["displayType"]))
, instead of this
TypeMismatch(expected: Int, actual: Optional(), keyPath: KeyPath(["dialog"]))
let json = loadJson("videoFileList_error.json") as! JSON
let _: ErrorObject.Data = try! decodeValue(json["error"]!["data"]!)
struct ErrorObject: Decodable {
let code: Int
let message: String
let data: Data?
struct Data: Decodable {
let dialog: Dialog?
let url: String?
struct Dialog: Decodable {
let title: String?
let message: String?
let displayType: Int?
{
"result": null,
"error": {
"code": 110,
"message": "",
"data": {
"dialog": {
"title": "",
"message": "",
"displayType": "" // This causes TypeMismatch because it's String instead of expected Int?.
},
"url": null
}
},
"id": "1",
"jsonrpc": "2.0"
}
Like that in Argo.
Hi,
Can you please help me with the following scenario?
I have a base object of type BaseObj like follows:
struct BaseObj {
let type: Int
}
and other classes that inherit from this one
struct ObjA: BaseObj {
let title: String
}
struct ObjB: BaseObj {
let description: String
}
my JSON looks like follows:
{
"objects":[
{
"type":1,
"title":"test title"
},
{
"type":2,
"description":"test description"
}
]
}
}
I would like my parser to return an array of BaseObj objects correctly initialized based on the type.
How would you go about parsing this response?
I would very much appreciate your help!
Thanks in advance.
Maybe this is a rare case, but building inside xcworkspace ends-up with runtime crash.
See: toshi0383/TVMLKitchen#142
I confirmed this happens with Himotoki, too.
I wonder if anybody have alternative work-around for this? Rather than adding ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
on library side?
Let's say I have two fields x
and y
in a JSON dictionary that I want to model as a single point in my model. How can I pass both fields to a transformer?
Thanks
👍 for this project! I'm going to add to my https://github.com/loretoparisi/ios-json-benchmark JSON comparison project.
I have a question. In terms of pure swift language
, using Apple's Foundation
creates a dependency from Cocoa
. Any way to get rid of it (no Cocoa
dependencies at all).
Thank you.
Have this entity:
struct Deal {
public let id: UInt64
public let name: String
public let dateCreated: Date
public let dateFinished: Date?
public let ownerUser: User?
public let currentUserIsOwner: Bool?
public let watchingUser: Bool?
public let status: Int?
public let dealMembers: [User]?
public let quantityUsers: Int?
}
in decode have error:
extension Deal: Decodable {
public static func decode(_ e: Extractor) throws -> Deal {
return try Deal(
id: e <| "Id",
name: e <| "Name",
dateCreated: e <| "DateCreated",
dateFinished: e <|? "DateFinished",
ownerUser: e <|? "OwnerUser",
currentUserIsOwner: e <|? "CurrentUserIsOwner",
watchingUser: e <|? "WatchingUser",
status: e <|? "Status",
dealMembers: e <||? "DealMembers",
quantityUsers: e <|? ""
)
}
}
on "dateCreated" have
Generic parameter 'T' could not be inferred
ok, try to delete this field, on "dateFinished" got this again. What is the problem?
macOS Sierra, Xcode 8, Swift 3.
Why Class in Swift can not decode by Himotoki?
such as :
class Hello: Decodable {
var text: String?
}
static func decode(_ e: Extractor) throws -> UserModel {
return try UserModel (
text : e <| "text",
)
}
Any plans to to add encoding implementation to framework?
Swift2.1 function is returnable Self
type in class, so I think we don't need DecodedType
now.
public protocol Decodable {
/// - Throws: DecodeError
static func decode(e: Extractor) throws -> Self
}
That is destructive change, but it has some advantages.
Decodable
because it has associated type.Decodable
, we will able to do it.DecodedType
bounds base class.In generic decodable type, Swift can't infer the type of initializer. For example:
struct PaginatedResponse<T: Decodable where T == T.DecodedType> {
let id: Int
let content: T
static func decode(e: Extractor) -> PaginatedResponse? {
let create = { PaginatedResponse($0) } // <- Missing argument for parameter 'content' in call
return build(
e <| "id",
e <| "content"
).map(create)
}
}
FYI, the code below passes build successfully.
struct PaginatedResponse<T: Decodable where T == T.DecodedType> {
let id: Int
let content: T
static func decode(e: Extractor) -> PaginatedResponse? {
let create = { id, content in
PaginatedResponse(id: id, content: content)
}
return build(
e <| "id",
e <| "content"
).map(create)
}
}
Do you have any idea to infer the type of initializer in the regular way?
Any operator for extracting [T?] ? (whole array isn't optional, second ? is for question)
I have an object Song
struct Song {
...
let frequencies: [[Int]]
}
and right now I'm parsing it so:
guard let arrayOfFrequencies = e.rawValue.valueForKeyPath("frequencies") as? [AnyObject] else {
throw customError("frequency parsing failed")
}
guard let twoD = arrayOfFrequencies.map({ $0 as? [Int] }) as? [[Int]] else {
throw customError("frequency parsing failed")
}
Is this the way I should be decoding it? Can I use Himotoki
to make my life easier?
DecodedType
associatedtype is removed in Himotoki 2.0, but that make it impossible to adopt class cluster pattern as filed in #118.
We should consider to re-introduce the requirement.
Hello! thanks for great tool. Please, add description for mapping to realm Object
Hi,
I have an issue decoding array of arrays,
how would you write a decode function which decode a JSON like this:
"summary": {
"items": [[0], [1], [2]]
}
I've tried writing a struct like this:
struct Summary {
let items: [[Int]]
}
and an extension:
extension Summary: Decodable {
static func decode(_ e: Extractor) throws -> Summary {
return try Summary(items: e <|| "items")
}
}
but I'm getting an error:
Type '[Int]' does not conform to protocol 'Decodable'
I know the JSON could be built better but this is what I'm getting from the server and this is what I have to decode.
Thanks,
Oron
It would be awesome for enum's that have a rawValue String to have implicit conformance to Decodable. If you think it's a good idea @ikesyo, I can go ahead and start a PR 😄
In Himotoki 1.3.0 release.
decode function crashes when nested object is not a dictionary.
struct Group: Decodable {
let locationName: String
static func decode(e: Extractor) throws -> Group {
return try Group(
locationName: e <| [ "location", "name" ] // Parse nested objects
)
}
}
func test() {
var JSON: [String: AnyObject] = [
"location" : "foo",
]
do {
let g: Group = try decode(JSON) // crash
} catch ...
}
It seems valueFor function (in Extractor.swift) assumes 'object' parameter is a dictionary.
In above example, string "foo" is passed as 'object' parameter then crash.
Thanks for your great lib. How can i extract nested params. For example, i want to get the value of name
in owner
.
e <| "owner,name"
When calling valueOptional with a value that might return null,
value
method is called, value
tries to decode a given keyPath, if the keyPath is null(which is logically correct since I called valueOptional),
value
throws on DecodeError.missingKeyPath
, which triggers swift exception break point.
Is there any future plans in solving this issue? maybe leading valueOptional through a different end point?
I am trying to decode a JSON like this one with Himotoki in Swift 3
next: [
{
question: 'Fréquence',
condition: { '==': ['answer', 'Actions'] },
},
{
question: 'Fréquence',
condition: { '>=': ['answer', 'Stop'] },
},
{
question: 'Risque',
condition: { '<=': ['answer', 'nul'] }
}
]
In the condition, there is an object that looks like a dictionary, since the field name changes ('==', '<=', '>=, ...). The value is then an array of string
I have tried to decode like this
typealias ConditionType = [String]
extension ConditionType: Decodable {}
struct NextItem {
let question: String?
let condition: [String : ConditionType]?
}
extension NextItem: Decodable {
static func decode(_ e: Extractor) throws -> NextItem {
return try NextItem(
question: e <|? "question",
condition: e <|-|? "condition"
)
}
}
I do not not how to decode the ConditionType since there is no field name for the array
Hi, I'm trying to create a generic functions that use generics that fetch a Decodable object with ReactiveCocoa.
I don't think the problem is due to ReactiveCocoa, but the Swift compiler itself.
Have you got an idea how I could solve this ?
static private func fetch<T: Decodable>(URLRequest: URLRequestConvertible) -> SignalProducer<T, NetworkError> {
return Network.request(URLRequest)
.attemptMap { JSON in
do {
// This next line is errored with "Ambiguous reference to member 'decode'
return .Success(try decode(JSON) as T)
} catch let error {
print("An error occured while decoding JSON: \(error)")
return .Failure(.IncorrectDataReturned)
}
}
}
Himotoki version 3.0.0
<|?
throws typeMismatch error where it should not.
e.g.
let json = ["hello": "1"]
let _: Int? = try e <|? "hello" // typeMismatch error is thrown.
I have an issue since i last updated my pods and Himotoki got upgraded to 2.0.0.
I no longer can use DecodedType and I have the following scenario I'd appreciate if you can help me fix.
I am subclassing a class which I need to be decodable like such:
class A: Decodable {
var type : Int = 0
var title: String = ""
init (e: Extractor) {
type = try! e <| "type"
title = try! e <| "title"
}
static func decode(e: Extractor) throws -> A {
let type : Int = try e <| "type"
switch type {
case 0:
return B(e: e)
case 1:
return C(e: e)
case 2:
return A(e: e)
}
}
}
class B: A {
var total : Double = 0.0
override init(e: Extractor) {
total = try! e <| "total"
super.init(e: e)
}
}
class C: A {
var link : String = ""
override init(e: Extractor) {
link = try! e <| "link"
super.init(e: e)
}
}
I now have a compiler error on this line static func decode(e: Extractor) throws -> A which says Method 'decode' in non-final class 'A' must return 'Self' to conform to protocol 'Decodable'
Thank you for your help in advance! Great library 👍 !
Hi, I really appreciate your library but I can't use it in current project because it doesn't support serialization. You seem don't want to had this feature in next releases. But why ? It would definitively be a good feature.
Swift 4.2 compatibility.
Please update.
Thanks!
It unclear from the README.md if Himotoki runs on Linux.
I have browsed around in the code and it mentions Linux several places.
Perhaps make it more clear that Linux is supported.
I have some JSON where one key path returns an Array<Dictionary<String,Any>>
, that is an array of [String:Any]
and I want to pass this to a Transformer
for manipulation into a different structure.
The issue I have is that Extractor
's array
and arrayOptional
methods expect to return an array of Decodable
T
. I can see why this works for Transformer<String, URL>
and the like thanks to the extensions in StandardLib.swift
, but [String:Any]
does not conform to Decodable
.
The only way I can get this to work is by adding an extension on Dictionary as follows:
extension Dictionary: Decodable {
public static func decode(_ e: Extractor) throws -> Dictionary<Key, Value> {
return try castOrFail(e.rawValue)
}
}
Is this correct? Should this be part of StandardLib.swift
, or am I approaching this in the wrong way?
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.