How to create objects from SwiftyJSON - swift

I have a code, that parses JSON's list of questions and I can get every property. How can I iterate through the whole file and for each question create an object ?
class ViewController: UIViewController {
var hoge: JSON?
override func viewDidLoad() {
super.viewDidLoad()
let number = arc4random_uniform(1000)
let url = NSURL(string: "http://www.wirehead.ru/try-en.json?\(number)")
var request = NSURLRequest(URL: url!)
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
if data != nil {
hoge = JSON(data: data!)
let level = hoge!["pack1"][0]["level"].intValue
let questionText = hoge!["pack1"][0]["questionText"].stringValue
let answer1 = hoge!["pack1"][0]["answer1"].stringValue
let answer2 = hoge!["pack1"][0]["answer2"].stringValue
let answer3 = hoge!["pack1"][0]["answer3"].stringValue
let answer4 = hoge!["pack1"][0]["answer4"].stringValue
let correctAnswer = hoge!["pack1"][0]["correctAnswer"].stringValue
let haveAnswered = hoge!["pack1"][0]["haveAnswered"].boolValue
}
}
}
my model of Question which objects I want to create below
class Question {
var level : Int?
var questionText : String?
var answer1 : String?
var answer2 : String?
var answer3 : String?
var answer4 : String?
var correctAnswer : String?
var haveAnswered : Bool = false
init(level: Int, questionText:String, answer1:String, answer2:String, answer3:String, answer4:String, correctAnswer: String, haveAnswered:Bool) {
self.level = level
self.questionText = questionText
self.answer1 = answer1
self.answer2 = answer2
self.answer3 = answer3
self.answer4 = answer4
self.correctAnswer = correctAnswer
self.haveAnswered = false
}
}

This is how I would approach the problem.
Step 1
Since your init inside Question does receive non optional objects, I had the feeling that the properties of Questions should be non optional too. I also converted the properties from var to let (tell me if I am wrong).
Step 2
This is the refactored Question class. As you can see I added a class method build that receive a JSON (a SwiftyJSON) and returns a Question (if the json contains correct data), nil otherwise.
Right now I cannot do this with a failable initializer.
extension String {
func toBool() -> Bool? {
switch self.lowercaseString {
case "true", "1", "yes" : return true
case "false", "0", "no" : return false
default: return nil
}
}
}
class Question {
let level: Int
let questionText: String
let answer1: String
let answer2: String
let answer3: String
let answer4: String
let correctAnswer: String
let haveAnswered: Bool
init(level: Int, questionText:String, answer1:String, answer2:String, answer3:String, answer4:String, correctAnswer: String, haveAnswered:Bool) {
self.level = level
self.questionText = questionText
self.answer1 = answer1
self.answer2 = answer2
self.answer3 = answer3
self.answer4 = answer4
self.correctAnswer = correctAnswer
self.haveAnswered = false
}
class func build(json:JSON) -> Question? {
if let
level = json["level"].string?.toInt(),
questionText = json["questionText"].string,
answer1 = json["answer1"].string,
answer2 = json["answer2"].string,
answer3 = json["answer3"].string,
answer4 = json["answer4"].string,
correctAnswer = json["correctAnswer"].string,
haveAnswered = json["haveAnswered"].string?.toBool() {
return Question(
level: level,
questionText: questionText,
answer1: answer1,
answer2: answer2,
answer3: answer3,
answer4: answer4,
correctAnswer: correctAnswer,
haveAnswered: haveAnswered)
} else {
debugPrintln("bad json \(json)")
return nil
}
}
}
Step 3
Now let's look at viewDidLoad.
func viewDidLoad() {
super.viewDidLoad()
let number = arc4random_uniform(1000)
if let
url = NSURL(string: "http://www.wirehead.ru/try-en.json?\(number)"),
data = NSURLConnection.sendSynchronousRequest(NSURLRequest(URL: url), returningResponse: nil, error: nil) {
// line #a
let rootJSON = JSON(data: data)
// line #b
if let questions = (rootJSON["pack1"].array?.map { return Question.build($0) }) {
// now you have an array of optional questions [Question?]...
}
}
}
At line #a I put inside rootJSON the whole data received from the connection (converted into JSON).
What happen at line #b?
Well I try to access the array located inside "pack1".
rootJSON["pack1"].array?
If the array exists I run the map method. This will extract each cell of the array and I will be able to refer to it with the $0 parameter name inside the closure.
Inside the closure I use this json block (that should represent a question) to build a Question instance.
The result will be an array of Question?. There could be ill values if some son data was not valid. If you want I can show you how to remove the nil values from this array
I could not try the code with real data, hope this helps.

Step 1. We will create one protocol with one constructor method in it and Model class
protocol JSONable {
init?(parameter: JSON)
}
class Style: JSONable {
let ID :String!
let name :String!
required init(parameter: JSON) {
ID = parameter["id"].stringValue
name = parameter["name"].stringValue
}
/* JSON response format
{
"status": true,
"message": "",
"data": [
{
"id": 1,
"name": "Style 1"
},
{
"id": 2,
"name": "Style 2"
},
{
"id": 3,
"name": "Style 3"
}
]
}
*/
}
Step 2. We will create extension of JSON which will convert JSON to model class type object
extension JSON {
func to<T>(type: T?) -> Any? {
if let baseObj = type as? JSONable.Type {
if self.type == .array {
var arrObject: [Any] = []
for obj in self.arrayValue {
let object = baseObj.init(parameter: obj)
arrObject.append(object!)
}
return arrObject
} else {
let object = baseObj.init(parameter: self)
return object!
}
}
return nil
}
}
Step 3. Use code with Alamofire or other code.
Alamofire.request(.GET, url).validate().responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
var styles: [Style] = []
if let styleArr = json["data"].to(type: Style.self) {
styles = styleArr as! [Style]
}
print("styles: \(styles)")
case .failure(let error):
print(error)
}
}
I hope this will be useful.
Please refer to this link for more information on this.
https://github.com/SwiftyJSON/SwiftyJSON/issues/714

You can use SwiftyJSONModel which was specifically designed for this purpose. So in your case the model would be like this:
class Question: JSONObjectInitializable {
enum PropertyKey: String {
case level, questionText
case answer1, answer2, answer3, answer4
case correctAnswer, haveAnswered
}
var level : Int?
var questionText : String?
var answer1 : String?
var answer2 : String?
var answer3 : String?
var answer4 : String?
var correctAnswer : String?
var haveAnswered : Bool = false
required init(object: JSONObject<PropertyKey>) throws {
level = object.value(for: .level)
questionText = object.value(for: .questionText)
answer1 = object.value(for: .answer1)
answer2 = object.value(for: .answer2)
answer3 = object.value(for: .answer3)
answer4 = object.value(for: .answer4)
correctAnswer = object.value(for: .correctAnswer)
haveAnswered = object.value(for: .haveAnswered) ?? false
}
}
And then do like this:
let rootJSON = JSON(data: data)
let questions = rootJSON.arrayValue.flatMap { try? Question(json: $0) }
The framework gives you several nice features:
All the keys are stored in separated enum PropertyKey
No boilerplate as stringValue, intValue etc.
If JSON will be invalid, framework will give a verbose error and you will immediately see what exactly went wrong

for (item, content) in hoge {
let level = content["level"].intValue
}
that should work

Related

Change a value in my UserModel (class) based on a userid

I have a UserModel:
class UserModel {
var uid: String?
var username : String?
var email: String?
var profileImageUrl: String?
var dateOfBirth: String?
var registrationDate: Int?
var isFollowing: Bool?
var accessLevel: Int?
var onlineStatus: Bool?
init(dictionary: [String : Any]) {
uid = dictionary["uid"] as? String
username = dictionary["username"] as? String
email = dictionary["email"] as? String
profileImageUrl = dictionary["profileImageUrl"] as? String
dateOfBirth = dictionary["dateOfBirth"] as? String
registrationDate = dictionary["userRegistrationDate"] as? Int
accessLevel = dictionary["accessLevel"] as? Int
onlineStatus = dictionary["onlineStatus"] as? Bool
}
}
And I also have a value like [12ih12isd89 : True]
I want to change the value "onlineStatus" for the user "12ih12isd89" to True and I thought the right way to do this is updateValue(:forKey:). But my class UserModel does not have updateValue(:forKey:).
How can I use this in my existing model?
Edit:
How I get the data:
func fetchAllUsers (completion: #escaping ([UserModel]) -> Void) {
let dispatchGroup = DispatchGroup()
var model = [UserModel]()
let db = Firestore.firestore()
let docRef = db.collection("users")
dispatchGroup.enter()
docRef.getDocuments { (querySnapshot, err) in
for document in querySnapshot!.documents {
let dic = document.data()
model.append(UserModel(dictionary: dic))
}
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
completion(model)
}
}
To me it looks like you need to find the right object in the array and update the property
let dict = ["12ih12isd89" : true]
var model = [UserModel]()
if let user = model.first(where: {$0.uid == dict.keys.first!}) {
user.onlineStatus = dict.values.first!
}
Depending on what ["12ih12isd89" : true] really is you might want to change the access from dict.keys.first! that I used
If your value dictionary contains more than one user, you can use a for loop like this:
var model = [UserModel]()
//Some initalization ...
let values = ["12ih12isd89" : true]
for (k, v) in values {
model.filter({$0.uid == k}).first?.onlineStatus = v
}

How to map the nested data in a document from Firestore by Swift?

I have a document data structure on Firestore like this:
pic1
pic2
So there are 2 map-objects inside the document and a collection and a another document inside this document
Then I create 3 model swift files for this document
task:
struct task {
var Name: String
var Address: String
var Car: CarModel
car Price: PriceModel
var dictionary: [String:Any] {
return [
"Name" : Name,
"Address" : Address,
"Car" : CarModel,
"Price" : PriceModel
]
}
init?(data: [String:Any]) {
guard let Name = dictionary["Name"] as? String,
let Address = dictionary["Address"] as? String,
let Car = ditionary["car"] as? CarModel,
let Price = dictionary["price"] as? PriceModel else{
return nil
}
self.Name = Name
self.Address = Address
self.Car = Car
self.Price = Price
}
}
CarModel:
struct CarModel {
var brand: String
var model: String
var year: String
var dictionary: [String:Any] {
return [
"brand" : brand,
"model" : model,
"year" : year,
]
}
init?(data: [String:Any]) {
guard let brand = dictionary["brand"] as? String,
let model = dictionary["model"] as? String,
let year = ditionary["year"] as? String else{
return nil
}
self.brand = brand
self.model = model
self.year = year
}
}
PriceModel:
struct PriceModel {
var basic: Int
var extra: Int
var dictionary: [String:Any] {
return [
"basic" : basic,
"extra" : extra,
]
}
init?(data: [String:Any]) {
guard let basic = dictionary["basic"] as? Int,
let extra = ditionary["extra"] as? Int else{
return nil
}
self.basic = basic
self.extra = extra
}
}
Then download the data with this following code:
func loadDataFromFirestore(completion: #escaping (Bool) -> ()) {
var success: Bool = false
DispatchQueue.global(qos: .userInteractive).async {
let downloadGroup = DispatchGroup()
let colRef = db.collection("tasks")
downloadGroup.enter()
colRef.getDocuments() { (querySnapshot, error) in
if let error = error {
print("Error: \(error)")
return
}
for document in querySnapshot!.documents{
let result = document.data()
print (result)
if let data = task(data: result){
print(data)
}
}
success = true
downloadGroup.leave()
}
downloadGroup.wait()
DispatchQueue.main.async {
completion(success)
}
}
}
I can get the data with comment the CarModel and PriceModel, but if I uncomment these two, it will let my app crash!
So how could I get the map-object to adapt to my code?
And the second question is: How can I get the document inside a document's collection with this kind of code?

Typecasting causing struct values to change (Swift)

After downcasting an array of structs, my Variables View window shows that all of the values in my struct have shifted "down" (will explain in a second). But when I print(structName), the values are fine. However, when I run an equality check on the struct, it once again behaves as though my values have shifted.
For example, I am trying to downcast Model A to ModelProtocol. var m = Model A and has the values {id: "1234", name: "Cal"}. When I downcast, m now has the values { id:"\0\0", name:"1234" }.
Actual Example Below:
Models that I want to downcast:
struct PrivateSchoolModel: Decodable, SchoolProtocol {
var id: String
var name: String
var city: String
var state: String
}
struct PublicSchoolModel: Decodable, SchoolProtocol {
var id: String
var name: String
var city: String
var state: String
var latitude: String
var longitude: String
}
Protocol I want to downcast to:
protocol SchoolProtocol {
var id: String { get set }
var name: String { get set }
var city: String { get set }
var state: String { get set }
var longitude: Float { get set }
var latitude: Float { get set }
}
extension SchoolProtocol {
var longitude: Float {
get { return -1.0 }
set {}
}
var latitude: Float {
get { return -1.0 }
set {}
}
}
Downcasting:
guard let downcastedArr = privateSchoolArray as? [SchoolProtocol] else { return [] }
Result (item at index 0) or originalArr:
id = "1234"
name = "Leo High School"
city = "Bellview"
state = "WA"
Result (item at index 0) of downcastedArr:
id = "\0\0"
name = "1234"
city = "Leo High School"
state = "Bellview"
But if I print(downcastArr[0]), it will show:
id = "1234"
name = "Leo High School"
city = "Bellview"
state = "WA"
But if I try originalArray[0].id == downcastArr[0].id, it returns false
My Code with the problem:
class SchoolJSONHandler {
private enum JSONFile: String {
case publicSchool = "publicSchool"
case privateSchool = "privateSchool"
}
private lazy var privateSchoolArray = getPrivateSchools()
private lazy var publicSchoolArray = getPublicSchools()
func getSchoolArray(sorted: Bool, filtered: Bool, by stateAbbreviation: String?) -> [SchoolProtocol] {
var schools = combineArrays()
if sorted {
schools.sort(by: { $0.name < $1.name })
}
if filtered {
guard let abbr = stateAbbreviation else { return [] }
schools = schools.filter {
return $0.state == abbr
}
}
return schools
}
private func combineArrays() -> [SchoolProtocol] {
// EVERYTHING IS FINE IN NEXT LINE
let a = privateSchoolArray
// PROBLEM OCCURS IN NEXT 2 LINES WHEN DOWNCASTING
let b = privateSchoolArray as [SchoolProtocol]
let c = publicSchoolArray as [SchoolProtocol]
return b + c
}
private func getPublicSchools() -> [PublicSchoolModel] {
guard let jsonData = getJSONData(from: .publicSchool) else { return [] }
guard let schools = decode(jsonData: jsonData, using: [PublicSchoolModel].self) else { return [] }
return schools
}
private func getPrivateSchools() -> [PrivateSchoolModel] {
guard let jsonData = getJSONData(from: .privateSchool) else { return [] }
guard let schools = decode(jsonData: jsonData, using: [PrivateSchoolModel].self) else { return [] }
return schools
}
private func getJSONData(from resource: JSONFile) -> Data? {
let url = Bundle.main.url(forResource: resource.rawValue, withExtension: "json")!
do {
let jsonData = try Data(contentsOf: url)
return jsonData
}
catch {
print(error)
}
return nil
}
private func decode<M: Decodable>(jsonData: Data, using modelType: M.Type) -> M? {
do {
//here dataResponse received from a network request
let decoder = JSONDecoder()
let model = try decoder.decode(modelType, from:
jsonData) //Decode JSON Response Data
return model
} catch let parsingError {
print("Error", parsingError)
}
return nil
}
}
And then it is just called in another class by schoolJSONHandler.getSchoolArray(sorted: true, filtered: true, by: "WA")

Firebase: How to put data in a child that's already created with childbyAutoID

people in my app sometimes needs to update the status of something. Now can you choose of 2 things: The so called "Rollerbank" is still there or the "Rollerbank" is removed. The users can create a data ref. The id that will be created by childbyAutoID. Now is my question how to get the right child and update some childs with a value. My post:
class Post {
let ref: DatabaseReference!
var TypeControle: String = ""
var Stad: String = ""
var Tijd: String = ""
var TijdControle: String = ""
var TijdControleniet: String = ""
var Latitude: String = ""
var Longitude: String = ""
var Extrainformatie: String = ""
var Staater: String = ""
var Staaternietmeer: String = ""
init(TypeControle: String) {
self.TypeControle = TypeControle
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(Stad: String){
self.Stad = Stad
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(Tijd: String) {
self.Tijd = Tijd
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(Latitude: String) {
self.Latitude = Latitude
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(Longitude: String) {
self.Longitude = Longitude
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(Extrainformatie: String) {
self.Extrainformatie = Extrainformatie
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(Staater: String) {
self.Staater = Staater
ref = Database.database().reference().child("Rollerbanken").child("Controletest").childByAutoId()
}
init(Staaternietmeer: String) {
self.Staaternietmeer = Staaternietmeer
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(TijdControle: String) {
self.TijdControle = TijdControle
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(TijdControleniet: String) {
self.TijdControleniet = TijdControleniet
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init() {
ref = Database.database().reference().child("Rollerbanken").childByAutoId()
}
init(snapshot: DataSnapshot)
{
ref = snapshot.ref
if let value = snapshot.value as? [String : Any] {
TypeControle = value["TypeControle"] as! String
Stad = value["Stad"] as! String
Tijd = value["Tijd"] as! String
Latitude = value["Latitude"] as! String
Longitude = value["Longitude"] as! String
Extrainformatie = value["Extrainformatie"] as! String
Staater = value["Staater"] as! String
Staaternietmeer = value["Staaternietmeer"] as! String
TijdControle = value["TijdControle"] as! String
TijdControleniet = value["TijdControleniet"] as! String
}
}
func save() {
ref.setValue(toDictionary())
}
func toDictionary() -> [String : Any]
{
return [
"TypeControle" : TypeControle,
"Stad" : Stad,
"Tijd" : Tijd,
"Latitude" : Latitude,
"Longitude" : Longitude,
"Extrainformatie" : Extrainformatie,
"Staater" : Staater,
"Staaternietmeer" : Staaternietmeer,
"TijdControle" : TijdControle,
"TijdControleniet" : TijdControleniet
]
}
}
Data for the TableViewCell:
class ControleTableViewCell: UITableViewCell {
#IBOutlet weak var storyControle: UILabel!
#IBOutlet weak var storyTijd: UILabel!
var post: Post! {
didSet {
storyControle.text = "\(post.Staaternietmeer)"
storyTijd.text = "\(post.TijdControleniet)"
storyControle.text = "\(post.Staater)"
storyTijd.text = "\(post.TijdControle)"
}
}
How my update button looks like:
#IBAction func Update(_ sender: Any) {
let alertController1 = UIAlertController(title: "Update melden" , message: "De rollerbank", preferredStyle: .alert)
// Create the actions
let RollerbankAction1 = UIAlertAction(title: "Staat er nog steeds", style: UIAlertActionStyle.default) {
UIAlertAction in
NSLog("Ja Pressed")
self.newStory.Staater = self.Staater
self.newStory.TijdControle = self.TijdControle
self.newStory.save()
}
let cancelAction1 = UIAlertAction(title: "Staat er niet meer", style: UIAlertActionStyle.cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
let date = Date()
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date)
let minutes = calendar.component(.minute, from: date)
let Tijd = "\(hour) : \(minutes)"
self.newStory.Staaternietmeer = self.Staaternietmeer
self.newStory.TijdControleniet = Tijd
self.newStory.save()
}
alertController1.addAction(RollerbankAction1)
alertController1.addAction(cancelAction1)
self.present(alertController1, animated: true, completion: nil)
}
This is the Structure that i use. If i run all this code, the new data will go in a other childbyAutoID and thats not what i want. It just needs to update/setvalue in the cleare space named "Staaternietmeer" and "TijdControleniet". Can anybody help me with that?
You would then need to store the Push ID somewhere so that you can reuse it later.
To generate a unique Push ID you would use :
Database.database().reference().childByAutoId()
And to store it somewhere :
let postKey = Database.database().reference().childByAutoId().key
And then, say you need a method to share a post for example, and want to add this post to multiple nodes, that's how it may look like :
func sharePost(_ postContent: String, completion: #escaping (Bool) -> ()) {
guard let currentUserId = Auth.auth().currentUser?.uid else {
completion(false)
return
}
let postKey = Database.database().reference().childByAutoId().key
let postData: [String: Any] = [ "content": "blabla",
"author": currentUserId ]
let childUpdates: [String: Any] = ["users/\(currentUserId)/posts/\(postKey)": true,
"posts/\(postKey)": postData ]
Database.database().reference().updateChildValues(childUpdates, withCompletionBlock: { (error, ref) in
guard error == nil else {
completion(false)
return
}
completion(true)
})
}
Now to access the unique Push ID later on, you would use :
Database.database().reference().observe(.childAdded, with: { (snapshot) in
// Here you get the Push ID back :
let postKey = snapshot.key
// And others things that you need :
guard let author = snapshot.childSnapshot(forPath: "author").value as? String else { return }
guard let content = snapshot.childSnapshot(forPath: "content").value as? String else { return }
// Here you store your object (Post for example) in an array, and as you can see you initialize your object using the data you got from the snapshot, including the Push ID (`postKey`) :
posts.append(Post(id: postKey, content: content, author: author))
})

groupBy array by two values in swift

I'm using this extension of Array to groupBy:
func groupBy <U> (groupingFunction group: (Element) -> U) -> [U: Array] {
var result = [U: Array]()
for item in self {
let groupKey = group(item)
// If element has already been added to dictionary, append to it. If not, create one.
if result.has(groupKey) {
result[groupKey]! += [item]
} else {
result[groupKey] = [item]
}
}
return result
}
And trying to make a dictionary from teamId and rank (custom properties of my object from array).
self.items = myArray.groupBy {
team in
if team.rank == nil {
return team.teamId!
} else {
return team.rank!
}
}
My case looks something like this:
[{
"team_id": "4",
"team_name": "T16",
"rank": "3"
},
,{
"team_id": "4",
"team_name": "T16",
"rank": "2"
},
{
"team_id": "4",
"team_name": "T16",
"rank": "1"
}
,{
"team_id": "5",
"team_name": "T16",
"rank": null
}]
desired output:
let teams : [String: TeamItem] = [ "4" : TeamItem.rank3, "4-2" : TeamItem.rank2, "4-1" : TeamItem.rank1, "5" : TeamItem]
EDIT 2
func requestTeamData(listener:([TeamItem]) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let baseURL: String = self._appSettings.getPathByName(EndPoint.BASE_URL.rawValue) as! String
let paths: NSDictionary = self._appSettings.getPathByName(EndPoint.PATH.NAME.rawValue) as! NSDictionary
let teamPaths: NSDictionary = paths.objectForKey(EndPoint.PATH.TEAM.KEY.rawValue) as! NSDictionary
let path = teamPaths.valueForKey(EndPoint.PATH.TEAM.PATH.rawValue) as! String
request(.GET, baseURL + path, parameters:[:])
.responseCollection { (_, _, team: [TeamItem]?, error) in
if let team = team {
dispatch_async(dispatch_get_main_queue()) {
listener(team)
}
}
}
}
}
Calling the API, straightforward
DataProvider.getInstance().requestTeamData({(items:[TeamItem]) -> () in
//Getting the items from the API
})
EDIT 1
#objc final class TeamItem: Equatable, ResponseObjectSerializable, ResponseDictionarySerializable {
let firstName: String?
let lastName: String?
let seasonId: String?
let seasonName: String?
let teamId: String?
let teamName: String?
let rank: String?
let positionId: String?
let positionName: String?
let number: String?
let birthDate: String?
let birthPlace: String?
let citizenship: String?
let height: String?
let weight: String?
let maritalStatus: String?
let model: String?
let hobby: String?
let food: String?
let book: String?
let movie: String?
let wish: String?
let message: String?
let biography: String?
let imageURL: String?
let teamImageURL: String?
required init?(response: NSHTTPURLResponse, representation: AnyObject) {
self.firstName = representation.valueForKeyPath(EndPoint.Keys.Team.FirstName.rawValue) as? String
self.lastName = representation.valueForKeyPath(EndPoint.Keys.Team.LastName.rawValue) as? String
self.seasonId = representation.valueForKeyPath(EndPoint.Keys.Team.SeasonId.rawValue) as? String
self.seasonName = representation.valueForKeyPath(EndPoint.Keys.Team.SeasonName.rawValue) as? String
self.teamId = representation.valueForKeyPath(EndPoint.Keys.Team.TeamId.rawValue) as? String
self.teamName = (representation.valueForKeyPath(EndPoint.Keys.Team.TeamName.rawValue) as? String)!
self.rank = representation.valueForKeyPath(EndPoint.Keys.Team.Rank.rawValue) as? String
self.positionId = representation.valueForKeyPath(EndPoint.Keys.Team.PositionId.rawValue) as? String
self.positionName = representation.valueForKeyPath(EndPoint.Keys.Team.PositionName.rawValue) as? String
self.number = representation.valueForKeyPath(EndPoint.Keys.Team.Number.rawValue) as? String
self.birthDate = representation.valueForKeyPath(EndPoint.Keys.Team.BirthDate.rawValue) as? String
self.birthPlace = (representation.valueForKeyPath(EndPoint.Keys.Team.BirthPlace.rawValue) as? String)!
self.citizenship = representation.valueForKeyPath(EndPoint.Keys.Team.Citizenship.rawValue) as? String
self.height = representation.valueForKeyPath(EndPoint.Keys.Team.Height.rawValue) as? String
self.weight = representation.valueForKeyPath(EndPoint.Keys.Team.Weight.rawValue) as? String
self.maritalStatus = representation.valueForKeyPath(EndPoint.Keys.Team.MaritalStatus.rawValue) as? String
self.model = representation.valueForKeyPath(EndPoint.Keys.Team.Model.rawValue) as? String
self.hobby = representation.valueForKeyPath(EndPoint.Keys.Team.Hobby.rawValue) as? String
self.food = representation.valueForKeyPath(EndPoint.Keys.Team.Food.rawValue) as? String
self.book = representation.valueForKeyPath(EndPoint.Keys.Team.Book.rawValue) as? String
self.movie = representation.valueForKeyPath(EndPoint.Keys.Team.Movie.rawValue) as? String
self.wish = representation.valueForKeyPath(EndPoint.Keys.Team.Wish.rawValue) as? String
self.message = representation.valueForKeyPath(EndPoint.Keys.Team.Message.rawValue) as? String
self.biography = representation.valueForKeyPath(EndPoint.Keys.Team.Biography.rawValue) as? String
self.imageURL = representation.valueForKeyPath(EndPoint.Keys.Team.ImageURL.rawValue) as? String
self.teamImageURL = representation.valueForKeyPath(EndPoint.Keys.Team.TeamImageURL.rawValue) as? String
}
#objc static func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [TeamItem] {
var teamItemArray: [TeamItem] = []
if let representation = representation as? [[String: AnyObject]] {
for teamItemRepresentation in representation {
if let teamItem = TeamItem(response: response, representation: teamItemRepresentation) {
teamItemArray.append(teamItem)
}
}
}
return teamItemArray
}
}
func ==(lhs: TeamItem, rhs: TeamItem) -> Bool {
return lhs.lastName == rhs.lastName
}
}
EDIT
TeamItem.rank1 means actually that the value of the rank is 1 (the same for others)
This is what've need, hope will help someone:
#objc static func dictionary(#response: NSHTTPURLResponse, representation: AnyObject) -> [String: Array<TeamItem>] {
var teamItemDictionary: [String: Array<TeamItem>] = [:]
if let representation = representation as? [[String: AnyObject]] {
for teamItemRepresentation in representation {
if let teamItem = TeamItem(response: response, representation: teamItemRepresentation) {
if teamItem.rank != nil {
let teamKey = teamItem.teamId! + "-" + teamItem.rank!
if teamItem.teamId != EndPoint.Keys.Team.Type.rawValue {
if let team = teamItemDictionary[teamKey] as [TeamItem]? {
teamItemDictionary[teamKey]?.push(teamItem)
} else {
teamItemDictionary[teamKey] = []
teamItemDictionary[teamKey]?.push(teamItem)
}
}
} else {
if teamItem.teamId != EndPoint.Keys.Team.Type.rawValue {
if let team = teamItemDictionary[teamItem.teamId!] as [TeamItem]? {
teamItemDictionary[teamItem.teamId!]?.push(TeamItem)
} else {
teamItemDictionary[teamItem.teamId!] = []
teamItemDictionary[teamItem.teamId!]?.push(TeamItem)
}
}
}
}
}
}
return teamItemDictionary
}