2

I want use ObjectMapper to parsing Json string within a singleton situation. Example code :

class User: Mappable {

    var username: String?
    var signature: String?

    //Singleton
    static let shared = User()
    private init() {}

    //Mappable functions
    required init?(map: Map) {}

    func mapping(map: Map) {
        username <- map["username"]
        signature <- map["signature"]
    }

    //Update userInfo after network request
    func getUserInfo() {
        //Network things
        ...
        //Example data
        let data = [
            "username": "Eason",
            "signature": "I love U"
        ]

        //Some thing like this to update userInfo
        Mapper<User>().map(data)
    } 

}

So, what is the right way to use ObjectMapper in singleton situation?

Hongxu Jin
  • 817
  • 2
  • 9
  • 16

1 Answers1

1

I prefer the following option.

1) UserManager (singleton):

class UserManager: NSObject {

    static let shared = UserManager()

    var profile: UserProfile?

    private override init() {}

    func loadUserProfile(completion: @escaping () -> ()) {

        RestClient.shared.getUserProfile() { [weak self] (profile, error) in

            guard let `self` = self else { return }

            self.profile = profile as? UserProfile

            completion()
        }
    }
}

2) User model:

class UserProfile: Mappable {

    var username: String?
    var signature: String?

    required init?() {}
    required init?(map: Map) {}

    func mapping(map: Map) {
        username   <- map ["username"]
        signature  <- map ["signature"]
    }

}

3) RestClient

typealias IdResponseBlock = (_ swiftObj: Any?, _ error: Error?) -> Void

class RestClient: NSObject {

    static let shared = RestClient()

    // Additional class where sending and receiving information from the server occurs
    private var http = HttpService()

    let baseUrl = ApiSettings.shared.kServerBaseURL

    override init() {
        super.init()
    }

    func parseData<P: BaseMappable>(object: Any, modelCls: P.Type, response: (IdResponseBlock)) {

        if object is NSArray {
            let result = Mapper<P>().mapArray(JSONObject: object)
            return response(result, nil)
        }

        if object is NSDictionary {
            let model: P = Mapper<P>().map(JSONObject: object)!
            return response(model, nil)
        }
    }

    //MARK: - API

    //MARK: - User

    func getUserProfile(resp: @escaping IdResponseBlock) {

        let url = baseUrl + Requests.profile

        http.queryBy(url, method: .get, queue: .background, resp: { (response, error) in

            if let err = error {
                return resp(nil, err)
            }

            guard let data = response else {
                return resp(nil, error)
            }

            let jsonData = JSON(data)["data"]

            self.parseData(object: jsonData.rawValue,
                           modelCls: UserProfile.self,
                           response: resp)
        })
    }
}
maxwell
  • 3,788
  • 6
  • 26
  • 40