我正在尝试学习MVVM设计模式并编写干净且可读的代码。问题是我从我将json响应对象映射到的对象获得nil值。我已经检查了我正在做的大部分事情,但我仍然得到了nils。这是我的代码。
搜索对象:
var eventsCollection = db.GetCollection<Event>("collection")
.WithReadPreference(ReadPreference.Nearest)
.AsQueryable()
.Where(e => e.EventDates.Any(ed => ed.EndDate >= DateTime.UtcNow));
视图模型
class SearchResultObj: NSObject {
var status : Bool
var name: String?
var publicKey: String?
var profileImage: String?
var accountType: String?
init (model: SearchResultObj) {
if let value = model.status as? Bool {
self.status = value
}else{
self.status = false
}
if let fullname = model.name {
self.name = fullname
}else{
self.name = nil
}
if let key = model.publicKey {
self.publicKey = key
}else{
self.publicKey = nil
}
if let profimage = model.profileImage {
self.profileImage = profimage
}else{
self.profileImage = nil
}
if let account = model.accountType {
self.accountType = account
}else{
self.accountType = nil
}
}
}
所以我在一个单独的类中进行服务调用,然后在完成处理程序中将响应传递给方法self.jsonMappingToSearch(json!as AnyObject)。之后我想将响应映射到我的SearchObject。当我打印出json对象的值时,我确实获得了实际值,但是在map函数运行后,我无法获得对象中的任何值,因为它返回所有nils。
答案 0 :(得分:0)
如果您真的在寻找干净,可读的代码,那么您应该查看Swift 4中的Codable Protocol。这样,您的代码就变成了以下内容,而不是有大量的手动JSON映射,应该处理jSON数据中的nils):
class SearchResultObj: NSObject, Codable {
var status = false
var name: String?
var publicKey: String?
var profileImage: String?
var accountType: String?
enum CodingKeys: String, CodingKey {
case status
case name = "fullName"
case publicKey
case profileImage = "image"
case accountType
}
}
func searchDataRequested(_ apiUrl: String,_ country: String,_ phone:String) {
let service = ServiceCall(urlServiceCall: apiUrl, country: country, phone: phone)
let url = URL(string: apiUrl)
let request = URLRequest(url: url!)
let country = country
let phone = phone
service.fetchJson(request: request, customerCountry: country, mobileNumber: phone) // making service call and returns json
{ (ok, json) in
print("CallBack response : \(String(describing: json))")
//I'm assuming your JSON is just a Data representation of the JSON string here
let decoder = JSONDecoder()
let result = decoder.decode(SearchResultObj.self, from: json)
//Add breakpoint or print to verify the result here
}
}
如果您可以发布源JSON,那么如果您仍然遇到问题也会有所帮助。
答案 1 :(得分:0)
init
你的searchDataRequested
函数,因此无法调用它。
因此,您的search
属性永远不会被分配SearchResultObj
的实例;它仍然是nil
。
如果您要在SearchResultObj
中指定一个空的init
,那么您也可以说
var search = SearchResultObj()
当您声明该属性时,您不需要init
,并且您不需要继续展开search
。
但我同意您应该使用Codable
此外,此代码无论如何都不符合MVVM架构。您的Model类将从网络中获取数据。 ViewModel仅用于在模型中的数据和应用程序中特定View所需的数据之间进行映射。
您需要使用某种形式的绑定,例如KVO或View Model和View之间的委托模式。
就个人而言,我不是iOS上MVVM的粉丝。该体系结构起源于内置数据绑定的Microsoft环境,因此MVVM更易于实现。在iOS上,您最终会增加复杂性,甚至可能甚至是第三方框架来实现绑定。
如果你刚开始使用iOS,我建议你先坚持使用MVC。