PPJSONSerialization alternatives and similar libraries
Based on the "JSON" category.
Alternatively, view PPJSONSerialization alternatives based on common mentions on social networks and blogs.
-
AlamofireObjectMapper
An Alamofire extension which converts JSON response data into swift objects using ObjectMapper -
Gloss
DISCONTINUED. [Deprecated] A shiny JSON parsing library in Swift :sparkles: Loved by many from 2015-2021 -
EVReflection
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift -
JSONHelper
✌ Convert anything into anything in one operation; JSON data into class instances, hex strings into UIColor/NSColor, y/n strings to booleans, arrays and dictionaries of these; anything you can make sense of! -
CodableAlamofire
DISCONTINUED. An extension for Alamofire that converts JSON data into Decodable objects. -
Genome
A simple, type safe, failure driven mapping library for serializing JSON to models in Swift 3.0 (Supports Linux) -
Elevate
Elevate is a JSON parsing framework that leverages Swift to make parsing simple, reliable and composable. -
JSONNeverDie
Auto reflection tool from JSON to Model, user friendly JSON encoder / decoder, aims to never die -
AlamofireJsonToObjects
An Alamofire extension which converts JSON response data into swift objects using EVReflection -
DynamicUI
Create a SwiftUI user interface through a JSON file. The JSON file will contain the structure of the user interface, and the program will create the user interface based on the JSON file.
CodeRabbit: AI Code Reviews for Developers

* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of PPJSONSerialization or a related project?
README
PPJSONSerialization 中文介绍
Introduce
There's a library, he make everything easier, faster, and safer.
It's a library, which handles all JSON operation in one class.
As we known, the JSON result always or sometimes make our app crash, because we don't even know that JSON data is completely correct. And we have Swift now! Swift is completely strong type and type safe. So, why should we still using Objective-C and Other JSON library?
Usage
Easy Startup
Just add
PPJSONSerialization.swift
to project (I'm not planning to publish it to CocoaPods, it's a tiny library.)Create your own class and subclass PPJSONSerialization
class Artist: PPJSONSerialization {
var name: String?
var height: Double = 0.0
}
- Fetch data from network and create an instance of your own class
let mockString = "{\"name\": \"Pony Cui\", \"height\": 164.0}"
let artistData = Artist(JSONString: mockString)
- Now, you can use it briefly
swift if let artistData = Artist(JSONString: mockString) { print(artistData.name) print(artistData.height) }
Features
Type transfer
Remember we set height
as Double
in Artist
Classes?
If the JSON type is in-correct, the most library will discard the result, or gives you an error message.
But PPJSONSerialization will try to convert it to Double
For example
let mockString = "{\"name\": \"Pony Cui\", \"height\": \"164.0\"}" //height is a string value
if let artistData = Artist(JSONString: mockString) {
print(artistData.name)
print(artistData.height) // Now it convert to Double, print 164.0
}
Type transfer now applys on string, double, int, bool
Optional value (Not stable)
The best feature in Swift is optional, PPJSONSerialization also support it.
class Artist: PPJSONSerialization {
var name: String? // We define it as an optional value
var height: Double = 0.0
}
let mockString = "{\"height\": \"164.0\"}"
if let artistData = Artist(JSONString: mockString) {
if let name = artistData.name {
print(name) // code will not execute, because the mockString doesn't contains name column.
}
}
Null crash or Invalid JSON
Never worry about that, the failable init will gives you the opportunity deal with that. Null value will never never never set to instance.
Array Generic support
The swift array always request a generic type define, you can't store another type in it. But JSON can! That's not an easy working while we using Objective-C.
PPJSONSerialization will handle this.
For example, you define a property friends
, all its member is String
value.
class Artist: PPJSONSerialization {
var name: String?
var height: Double = 0.0
var friends = [String]()
}
Just use it as below, note that we have 3 invalid types, but PPJSONSerialization will convert it.
let mockString = "{\"friends\": [\"Jack\", \"Leros\", \"Max\", \"LGY\", 1, 2, 3]}"
if let artistData = Artist(JSONString: mockString) {
for friend in artistData.friends {
print(friend)
}
}
/*
Prints:
Jack
Leros
Max
LGY
1
2
3
*/
Dictionary Generic support
The dictionary generic is also support as Array. But I strongly recommend you use Sub-Struct to deal with Dictionary.
class Artist: PPJSONSerialization {
var name: String?
var height: Double = 0.0
var friendsHeight = [String: Double]() // now we change it as dictionary
}
let mockString = "{\"friendsHeight\": {\"Jack\": 170, \"Leros\": 180, \"Max\": 168, \"LGY\": 177}}"
if let artistData = Artist(JSONString: mockString) {
for (friend, height) in artistData.friendsHeight {
print("\(friend), height:\(height)")
}
}
/*
Prints:
Leros, height:180.0
Max, height:168.0
LGY, height:177.0
Jack, height:170.0
*/
Custom Type (Sub-Struct)
There's a really common situation is a dictionary contains another dictionary, you can use Dictionary Generic handle this, right? But, if you eager the model much easier to manage, or much pettier. Custom Type is really important for you.
Note: Custom Type can use in Dictionary/Array/Property either.
class Artist: PPJSONSerialization {
var name: String?
var height: Double = 0.0
var friends = [ArtistFriend]()
}
// The Sub-Struct either subclasses PPJSONSerialization
class ArtistFriend: PPJSONSerialization {
var name: String?
var height: Double = 0.0
}
let mockString = "{\"friends\": [{\"name\": \"Jack\", \"height\": \"177.0\"}, {\"name\": \"Max\", \"height\": \"188.0\"}]}"
if let artistData = Artist(JSONString: mockString) {
for friend in artistData.friends {
print("\(friend.name), height:\(friend.height)")
}
}
/*
Prints:
Optional("Jack"), height:177.0
Optional("Max"), height:188.0
*/
PPCoding
If you eager to control type transferring. Follow PPCoding protocol.
For example, we eager to transfer an timestamp(Int) to NSDate, that's a common requirement.
class CodeingStruct: PPJSONSerialization {
var codeingDate: NSDate = NSDate() // Define a property as common, optional or non-optional available either.
}
extension NSDate: PPCoding {
func encodeAsPPObject() -> AnyObject? {
return timeIntervalSince1970
}
func decodeWithPPObject(PPObject: AnyObject) -> AnyObject? {
if let timestamp = PPObject as? NSTimeInterval {
return NSDate(timeIntervalSince1970: timestamp) // And now we extent NSDate
}
return nil
}
}
let codingDateJSON = "{\"codeingDate\":1444885037}"
if let test = CodeingStruct(JSONString: codingDateJSON) {
XCTAssert(test.codeingDate.description == "2015-10-15 04:57:17 +0000", "Pass")
}
- PPCoding also support serialize operation.
- Optional value is not available for serialize.
Array JSON
If the JSON is an array base struct. You should subclass PPJSONArraySerialization
, and define a property root
with generic type.
class ArrayStruct: PPJSONArraySerialization {
var root = [Int]()
}
let arrayJSON = "[1,0,2,4]"
if let arrayObject = ArrayStruct(JSONString: arrayJSON) {
XCTAssert(arrayObject.root.count == 4, "Pass")
XCTAssert(arrayObject.root[0] == 1, "Pass")
XCTAssert(arrayObject.root[1] == 0, "Pass")
XCTAssert(arrayObject.root[2] == 2, "Pass")
XCTAssert(arrayObject.root[3] == 4, "Pass")
}
Multiple Dimension Array
If the array contains array, it should define like this.
class MultipleDimensionArray: PPJSONSerialization {
var twoDimension = [[Int]]()
var threeDimension = [[[Int]]]()
}
let twoDimensionArrayJSON = "{\"twoDimension\": [[1,0,2,4], [1,0,2,4]]}"
if let test = MultipleDimensionArray(JSONString: twoDimensionArrayJSON) {
XCTAssert(test.twoDimension[0][0] == 1, "Pass")
XCTAssert(test.twoDimension[0][1] == 0, "Pass")
XCTAssert(test.twoDimension[0][2] == 2, "Pass")
XCTAssert(test.twoDimension[0][3] == 4, "Pass")
XCTAssert(test.twoDimension[1][0] == 1, "Pass")
XCTAssert(test.twoDimension[1][1] == 0, "Pass")
XCTAssert(test.twoDimension[1][2] == 2, "Pass")
XCTAssert(test.twoDimension[1][3] == 4, "Pass")
}
Key Mapping
Sometimes, network data key column is different to app's, there's relly simple way to handle this. Override the mapping method, and return a dictionary contains ["JSONKey": "PropertyKey"]
class Artist: PPJSONSerialization {
var name: String = ""
var height: Double = 0.0
override func mapping() -> [String : String] {
return ["xxxname": "name"]
}
}
let mockString = "{\"xxxname\": \"Pony Cui\"}"
if let artistData = Artist(JSONString: mockString) {
print(artistData.name)
}
Serialize
You use serialize to serialize PPJSONSerialization classes to JSON String or JSON Data, it's a perfect way to deliver data to server.
class Artist: PPJSONSerialization {
var name: String = "" // Optional value is also supported.
var height: Double = 0.0
}
let artistData = Artist()
artistData.name = "Pony Cui"
artistData.height = 164.0
let string = artistData.JSONString()
print(string)
/*
Prints: {"name":"Pony Cui","height":164}
*/
Namespace support
You may define a class wrapping classes in Swift. That's a good practice.
Here is an example, we put all PPJSONSerialization classes in DataModel namespace
class DataModel { // Struct & Enum also available
class Artist: PPJSONSerialization {
var name: String?
var mainSong = Song() // Using namespace, you must init an instance. Optional type is not availabel.
var songs = [Song()] // Using namespace, you must init an instance in array!
var mapSong = [".": Song()] // Using namespace, you must init an instance in dictionary with any key!
}
class Song: PPJSONSerialization {
var name: String?
var duration: Double = 0.0
}
}
let JSONString = "{\"name\": \"Pony Cui\", \"mainSong\": {\"name\":\"Love Song\", \"duration\": 168.0}, \"songs\": [{\"name\":\"Love Song\", \"duration\": 168.0}], \"mapSong\": {\"sampleKey\": {\"name\":\"Love Song\", \"duration\": 168.0}}}"
if let test = DataModel.Artist(JSONString: JSONString) {
XCTAssert(test.name! == "Pony Cui", "Pass")
XCTAssert(test.mainSong.name == "Love Song", "Pass")
XCTAssert(test.mainSong.duration == 168.0, "Pass")
XCTAssert(test.songs[0].name == "Love Song", "Pass")
XCTAssert(test.songs[0].duration == 168.0, "Pass")
XCTAssert(test.mapSong["sampleKey"]?.name == "Love Song", "Pass")
XCTAssert(test.mapSong["sampleKey"]?.duration == 168.0, "Pass")
}
else {
XCTAssert(false, "Failed")
}
- Multiple level nampspace is available.
Sub-Class
You can subclass your struct, it's okey.
class CommonResponse: PPJSONSerialization {
var error: String?
}
class ArtistResponse: CommonResponse {
// ...
}
PPJSONSerialization is still in development, welcome to improve the project together.
Requirements
- iOS 7.0+ / Mac OS X 10.10+
- Xcode 7.0
- Swift 2.0
Integration
Add PPJSONSerialization.swift
into your project, that's enough
License
MIT License, Please feel free to use it.
Thanks
- Thanks for @onevcat suggest use Failable init.
- Thanks for @neil-wu using and reported issues.
*Note that all licence references and agreements mentioned in the PPJSONSerialization README section above
are relevant to that project's source code only.