Sathya Baman
Sathya Baman

Reputation: 3515

Swift Compact Map returning empty

Hi I am trying to learn RXSwift and First time I came across these concepts like Maps and Compact Maps.

I am able to get the response, but this line always returns empty.

objects.compactMap(DummyUser.init)

fileprivate let Users = Variable<[DummyUser]>([])
    fileprivate let bag = DisposeBag()



response
                .filter { response, _ in
                    return 200..<300 ~= response.statusCode
                }
                .map { _, data -> [[String: Any]] in
                    guard (try? JSONSerialization.jsonObject(with: data, options: [])) != nil  else {
                            return []
                    }

                    let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]

                  //  print(json!["results"])
                    return json!["results"] as! [[String : Any]]
                }
                .filter { objects in
                    return objects.count > 0
                }
                .map { objects in
                  //  objects.forEach{print($0["name"]!)}
                    let names = objects.map { $0["name"]!}
                    print(names)
                    return objects.compactMap(DummyUser.init)
                }
                .subscribe(onNext: { [weak self] newEvents in
                    self?.processEvents(newEvents)
                })
                .disposed(by: bag)

func processEvents(_ newEvents: [DummyUser]) {
        var updatedEvents = newEvents + Users.value
        if updatedEvents.count > 50 {
            updatedEvents = Array<DummyUser>(updatedEvents.prefix(upTo: 50))
        }

        Users.value = updatedEvents
        DispatchQueue.main.async {
            self.MianUsertable.reloadData()
        }
     //   refreshControl?.endRefreshing()

        let eventsArray = updatedEvents.map{ $0.dictionary } as NSArray
        eventsArray.write(to: userFileURL, atomically: true)

    }

My Json Response is Here

https://randomuser.me/api/?results=5

DummyUser Class

import Foundation

typealias AnyDict = [String: Any]

class DummyUser {
    let gender: String
    let name: AnyDict
    let dob: String
    let picture: AnyDict

    init?(dictionary: AnyDict) {
        guard let Dgender = dictionary["gender"] as? String,
             let Dname = dictionary["name"] as? AnyDict,
             let birthdata = dictionary["dob"] as? AnyDict,
             let Ddob = birthdata["dob"] as? String,
             let Dpicture = dictionary["picture"] as? AnyDict
            else {
                return nil
        }

        gender = Dgender
        name = Dname
        dob = Ddob
        picture = Dpicture
    }



    var dictionary: AnyDict {
        return [
            "user": ["name" : name, "gender": gender, "dob": dob],
            "picture" : ["userImage": picture]
        ]
    }

}

Upvotes: 1

Views: 2184

Answers (1)

Michał Kwiecień
Michał Kwiecień

Reputation: 2874

In your DummyUser model you are using failable initializer, so in case of wrong dictionary provided to init method it will return nil.

compactMap automatically automatically filters nil's and that's the reason why your output is empty.

Looking at this piece of code:

let names = objects.map { $0["name"]!}
return objects.compactMap(DummyUser.init)

I would debug this variable called names because it probably has wrong input for the DummyUser initializer. It should be dictionary containing all of your DummyUser parameters. You can also debug your failable initializer to see which of the parameter is missing.

Upvotes: 1

Related Questions