Giter Site home page Giter Site logo

marshal's People

Contributors

benjaminsnorris avatar bjarkehs avatar brianmullen avatar bwhiteley avatar derrh avatar iosdevzone avatar jarsen avatar jetforme avatar jgrandelli avatar natebird avatar rpeckatl avatar timshadel avatar zeveisenberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marshal's Issues

Add support for Swift basic data types.

We are missing the following:

Int8
Int16
Int32
UInt8
UInt16
UInt32
UInt64
Character
Float80 - This isn't available on all platforms and so we may not want to include it.

Add a protocol so we can update/configure existing objects.

We already have support to create new objects and so it seems logical that we add a protocol for updating/configuring existing objects.

Something like the following:

public protocol ObjectConfigurable
{
     func configure( object: Object )
}

Handling JSON where top level structure is an array not a dictionary

Hello,

Very interested in using Marshal however I'm not sure how best to handle JSON where the top level structure is an array rather than a dictionary.

We have some JSON that looks like this:

 [
  {
  "id": "111",
  "firstname":"John",
  "surname": "Doe"
  }, {
  "id": "222",
  "firstname":"Jane",
  "surname": "Doe"
}
]

We would like to be able to map this directly into say an array of Users where User conforms to Unmarshaling i.e.

struct User: Unmarshaling {
    var id: Int
    var firstname: String
    var surname: String

    init(object: MarshaledObject) throws {
        id = try object.value(for: "id")
        firstname = try object.value(for: "firstname")
        surname = try object.value(for: "surname")
    }
}

However the library seems to always need a key in order to create the unmarshaled object. The only way I can see to do this now is to have something like:

var jsonObjects: [JSONObject] = try! JSONParser.JSONArrayWithData(data)
    for obj in jsonObjects {
         let user = User()
         user.id = try obj.value("id")
         user.firstname = try obj.value("firstname")
        user.surname = try obj.value("surname")
    }

This does not seem as elegant as being able to create the array of users directly i.e.

let users: [User] = try json.value("users")

What is the best way of handling this kind of JSON format using Marshal?

Thanks

no pod ??

please provide pod for your mapper project ๐Ÿ™๐Ÿป

Abiguous use of operator/function with enum

Hi!

I experienced a small problem when using enums as ValueTypes. I have an enum in a project defined as the following:

enum Week: Int {
    case all = 0, even, odd
}

I implemented the ValueType extension as the following:

extension Week: ValueType {
    public static func value(from object: Any) throws -> Week {
        guard let raw = object as? RawValue else {
            throw MarshalError.typeMismatch(expected: RawValue.self, actual: type(of: object))
        }
        guard let week = Week(rawValue: raw) else {
            throw Error.outOfBounds(raw)
        }
        return week
    }
}

When using this in a type that has a Week property, I get the compiler error 'ambiguous use of X' where X is either <| or value(for:).

I fixed it by using this code in my type that is using Week, but the solution is not that satisfiying. Do you have any other ideas?

let rawWeek: Int = try object <| "week"
guard let week = Week(rawValue: rawWeek) else {
    throw Week.Error.outOfBounds(rawWeek)
}
self.week = week

Thanks in advance!

Parsing objects no longer works

We recently updated to v0.9.6, and found that some parsing is now broken. Previously, we could do

let dictionary: [String: Bool] = try object <| key

Now, I have to do something more like:

guard let dictionary = try object.anyForKey(key) as? [String: Bool] else { throw _ }

Another example is that I previously did this without problem:

let dictionary: [String: [String: JSONObject]] = try object <| key

ERR: Pod No such Module

Hello together,

everythink worked fine. Then I added an other pod and deleted it again. And now I always get following error while importing

../ViewController.swift:11:8: No such module 'Marshal'

I also deintegrate and did pod init on my project. I still get the error.

What could be the Problem?
Do you have any suggestions for me to check?

Kind Regards
Alexander Niebuhr

Support for iOS8

We should lower the deployment target to support the prior iOS version. There is no technical limitation for us to exclude iOS 8.

Document `discardingErrors`

We have the discardErrors flag for helping deal with arrays with invalid elements, but it isn't really documented.

UnmarshalingWithContext with init

When looking at the differences between Unbox and Marshal, I was surprised to see the UnmarshalingWithContext protocol not use an init like Unbox. Is there a reason for that? Seems a bit less elegant.

For reference:

public protocol UnboxableWithContext {

    /// The type of the contextual object that this model requires when unboxed
    associatedtype UnboxContext

    /// Initialize an instance of this model by unboxing a dictionary & using a context
    public init(unboxer: Unbox.Unboxer, context: Self.UnboxContext) throws
}

Difficulties parsing JSON Objects

Hi guys, I really want to thank you for you awesome work, I think Marshal is the fastest and lightweight library to deal with JSON structures.
I'm facing a problem parsing a simple data structures:

"students": {
     "mrngcm":{
         "first_name":"John",
         "last_name":"Doe",
         "courses": {
             "MAT": 28
         }
     }
     ...
}

Here my model class:

import Foundation
import Marshal

class Student: Unmarshaling {
    var id: String
    var firstName: String
    var lastName: String
    var courses: [String:Int]
    
    required init(object: MarshaledObject) throws {
        self.firstName = try object.value(for: "first_name")
        self.lastName = try object.value(for: "last_name")
        self.courses = try object.value(for: "courses")
    }
}
let json: MarshalDictionary = try! JSONSerialization.jsonObject(with: dataFromString, options: []) as! MarshalDictionary
let students: [String: Student] = try! json.value(for: "students")

I don't exactly how to assign key to model id and additionally I'm getting and error while extracting courses dictionary: fatal error: try!' expression unexpectedly raised an error: Type mismatch. Expected type Dictionary<String, Int> for key: courses. Got '__NSArray0

Do you have any suggestion? Thank you so much

JSON array to String

How can Marshal be extended to allow converting a JSON like this:

"somekey": ["s1", "s2", "s3"]

into this

"s1,s2,s3"

I had few multiple false starts already, can't figure it out.

Marshalling array of different subclasses.

How can I unmarshall JSON that contains an array of different subclasses?

We're using ObjectMapper right now but I have some issues with the heavy use of unwrapped optionals and handling data validation.

Could we able to parse root level custom object array ?

how to parse following ?

[
    {"name": "alex","gender" : "male", "expertise_in" : "ios"},
    {"name": "stacy","gender" : "female", "expertise_in" : "swift"},
    {"name": "bob","gender" : "male", "expertise_in" : "objc"}
]

does if we don't able to parse this then there is any work around or does there is any plan for support it in future road map ?

Currently i am doing something like this

    let objs : [JSONObject] = try JSONParser.JSONArrayWithData(response.data!)
    let persons :[Person] = try objs.map({ (dict) -> Person in
         return try Person(object: dict)
    })

how do I force String typing of a JSON value

I have the JSON object:

 {
 "accountId" : 8954947,
 "accountName" : "Primary",
 "accountCurrency" : "USD",
 "marginRate" : 0.05
 }

I want to decode it to:

struct AccountSummary: Unmarshaling
{
    let id: String
    let name: String
    let currency: Currency
    let marginRate: Double
    
    init(object: MarshaledObject) throws
    {
        try id = object.value(for: "accountId")
        name = try object.value(for: "accountName")
        currency = try object.value(for: "accountCurrency")
        marginRate = try object.value(for: "marginRate")
    }
}

id throws Marshal.MarshalError error 3 because it only sees an Int. How can I force it to read a String

Add travis CI integration

To help alleviate build issues, we should add support for travis CI so that we can verify builds before merging pull requests.

Cocoapods (Actually pushing to Trunk)

Hi,

I see a lot of issues around Cocoapods right now, and it stems from people not actually being able to access the podspec, without specifying the git url. In order to fix this then @psychoticidiot needs to run pod trunk push Marshal.podspec.

This will release version 1.2.3 to cocoapods.org, and can then be found with a simple `pod 'Marshal', '~> 1.2'.

Right now you have to do: pod 'Marshal', :git => 'https://github.com/utahiosmac/Marshal.git'.

I hope this clarifies things. If you want, you can add me as a maintainer of the pod, and I'll make sure it gets updated on Trunk.

Progress to user when parsing many records?

I could use a suggestion on how to best provide progress when parsing a JSON array of a zillion records. Been using the frameworks simple syntax to unmarshal the array with my object implementing Unmarshaling protocol. Works perfectly fine, but when I have many records, how can I provide a 'percent complete' back to the user?

`
// This one liner blasts thru the millions of elements in my JSON array to unmarshal,
// but doesn't let me know which index its on so I can give the user progress feedback.

let records: [MyRecord] = try? jsonObject.value(for: "BillonsOfRecords")
`

How to marshal array of arrays?

I'm trying to marshal a property like:

var arrayOfArrayOfThings: [[Thing]]? 
// ... later on ...
arrayOfArray = try object.value(for: "arrayOfArrayOfThings") 

Where Thing is a Unmarshaling. But I get a No 'value' candidates produce the expected contextual result type '[[Thing]]?'. I tried defining extensions to MarshableObject.value that return [[A]] but got stuck. It seems like for Array<Array<A>> Swift doesn't recognize the inner Array<A> type as a ValueType?

Core Data and NSManagedObject

Hi, I really like your approach with Marshal and I wanted to implement it in my project.
However, I'm currently using core Data and my objects are NSManagedObjects.

I'm trying to find a way to coexist Marshal and Core Data, but I haven't found any working solution yet. Did you already tried something similar?

Thanks a lot

Podspec update as part of release cycle

Thanks for the great lib. I removed another older, less performant lib that served us well for a long time to move to this much lighter and flexible approach... and it's great.

Is there any way we can get the Podspec version updates for releases? I use this in a stand alone http client dynamic lib. Would be great to get the fixes when you release them ๐Ÿ˜…

Change definition of `MarshaledObject` to `[String: Any]`?

@bwhiteley @jarsen (and anyone else that wants to chime in)

We have been talking about making the core of this library generic. I just realized that we cant store native Swift data types (Int8, Int16, Int32, Int64, UInt, etc) since the values of MarshaledObject have to be AnyObject (which means all of our number extractions need to be adjusted to always pull values out of an NSNumber).

I have been thinking about how we might get data from any source. So, thinking along those line we also need to evaluate how we convert basic data types from one data type to another. Parsing JSON with odd formats might benefit from this, for example, a service might wrap some integer as a string and so instead of having the consumer pull out a string and then cast it as an integer, we could make use of the builtin data type conversions and do that for them automatically. This way the only time a consumer needs to do something like that is in those odd/rare cases.

I have been working on some initial code (attached) that would convert it over but I don't want to go too far until we have discussed it. I have passing unit tests written up as well and have tested it on mac and iOS (both 32bit & 64bit) for all data types. We would still need to adjust some additional code, for example the array extraction doesn't work if the values are Any.

What do you think?
ValueType.swift.zip

Expected type Date for key...

Sometimes I get into a situation where Date parsing doesn't seem to work.

This:

self.createdAt = try json.value(for: "created_at")

Throws this:

Type mismatch. Expected type Date for key: created_at. Got '__NSCFString'

I can work around this by transforming to a string first, then to Date:

let s: String = try json.value(for: "created_at")
self.createdAt = try Date.value(for: s)

My Date support looks like so:

extension Date {
    @nonobjc static let ISO8601SecondFormatter:DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ";
        formatter.timeZone = TimeZone(abbreviation:"GMT")
        return formatter
    }()
    
    static func fromISO8601String(_ dateString:String) -> Date? {
        if let date = ISO8601SecondFormatter.date(from: dateString) {
            return date
        }
        return .none
    }
}
extension Date : ValueType {
    public static func value(_ object: Any) throws -> Date {
        guard let dateString = object as? String else {
            throw MarshalError.typeMismatch(expected: String.self, actual: type(of: object))
        }
        guard let date = Date.fromISO8601String(dateString) else {
            throw MarshalError.typeMismatch(expected: "ISO8601 date string", actual: dateString)
        }
        return date
    }
}

Expose `anyForKey` in the dictionary extension

In case there are situations where another dataType comes along that doesn't fall under our current dictionary extension, it would be helpful for users to utilize the existing code to write their own dictionary extensions to handle that dataType. For example, we don't currently support the Swift Set type and so users are left to manually extract as an Array and then pass it to the Set constructor.

We should change private func anyForKey to public func anyForKey

Error building Marshal using Carthage

I'm updating my app to Swift 3.1 and I ran carthage update after installing Xcode 8.3 and swift 3.1.

While building Marshal if fails with the following: <unknown>:0: warning: argument unused during compilation: '-iapinotes-modules /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/arm64'

I don't think it is Marshal specific because I checked out the Marshal repo and it builds fine. However, this is the only framework where I get this error. Any ideas of how I can work around this warning? Internet search says to pass -Qunused-arguments but is that possible with Carthage?

Is it possible to unmarshal a [String: AnyObject] directly without calling .value()?

I, unfortunately, have some API endpoints that return responses which are objects that I would like to unmarshal. So say I get something that's a user object back:

{"username": "eric", "id": 1}

From my API, I get this value as a [String: AnyObject], so there is no opportunity to call .value() on it. I simply want to convert it directly to an object.

Is the only option to re-wrap the [String: AnyObject] in another [String: AnyObject]? Or can I somehow unmarshal a [String: AnyObject] directly?

Add support for `Set`

We have Array and Dictionary support. Set is another core type we should support.

Support Date marshalling with different formatters

I'm currently using Unbox but am seriously thinking of switching to Marshal. But it has one major problem for me. The way that Date gets marshalling support by conforming to a protocol means I can't have dates parsed with different formatters. This is a real problem for applications that needs to parse JSON from different APIs that represent dates differently.

Any ideas of improving this?

Unmarshaling into dictionary [String: CustomObject]?

Hello,

I'm having some trouble unmarshalling some JSON that has a field that looks like:

{
"people" : {
  "person_id1": {
       "name": "some_name1"
       "birthday": "19/2/90"
  },
  "person_id2": {
       "name": "some_name2"
       "birthday": "10/1/88"
  },
  "person_id3": {
       "name": "some_name3"
       "birthday": "30/6/92"
  }
}
}

After parsing the JSON response, i'm trying to unmarshal it into my model like so:

let people: [String: Person] = json.value(for: "people")

But it keeps failing with the typeMismatchWithKey error with:

key = people
expected = Person
actual = __NSDictionaryI

I'm not too sure what I'm doing wrong -do I need to write a custom valueType extension to unpack this like in the Readme?

Decode value with leading-dot key

How to get value for key ".tag" from this JSON:

{
    ".tag": "test"
    "name": "something"
}

Marshal splits the key by ., so object.value(for: ".tag") returns nil because tag key is not found.

Support for Arrays of Optionals

It would be nice to have built in support for marshaling arrays of optionals. That way if an object in an array fails to initialize/throws during initialization it doesn't throw out the entire array.

Support for discarding invalid objects in arrays

#68 Allows arrays of optionals so objects that fail to initialize will be result in optionals in the array. This would add functionality to drop nil values from arrays. Both this and #68 would enable the ability to serialize data that can be and discard that which can't be instead of throwing it all out. Addressing these two issues would add great flexibility to parsing arrays of objects while not breaking current behavior.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.