如何在 Swift 3 中为来自 web 服务的 Json 响应创建模型类
Posted
技术标签:
【中文标题】如何在 Swift 3 中为来自 web 服务的 Json 响应创建模型类【英文标题】:How to create model class for Json response from webservice in Swift 3 【发布时间】:2017-12-21 07:28:50 【问题描述】:我是 swift 新手。我正在做 swift 项目。我从服务器响应中得到响应,如下所示
kNetworkManager.executePostRequest(urlString: kAppSocialLoginURL, params:mainDictionary, requestVC: self,completionHandler: (responseObject) -> () in
// print("response object:\(responseObject!)")
if responseObject != nil
let responseDictionary = responseObject as! NSDictionary
if responseDictionary is NSDictionary
let obj = responseDictionary.value(forKey:"user")
if obj is NSDictionary //success case
print("NSDictionary is",obj ?? NSDictionary())
UtilityClass.sharedInstance.userDetailsDictionary = responseDictionary as! [String : AnyObject]
if let obj = responseDictionary.value(forKey:"user") as? NSDictionary
if let sessionId = obj["token"] as? String
UtilityClass.sharedInstance.kSessionIDString = sessionId
if let userObj = obj["user"] as? NSDictionary
在上面的代码中,我多次检查它是否是字典,或者分配为字典。我在我所有的课上都在做这种练习。所以,我想为通用逻辑创建一些模态类,并且我想在获取 Web 服务数据后在每个类中使用该逻辑。
我的网络服务响应如下
user =
sessid = "-qadadadad";
"session_name" =aadadad;
tokenData = adadadad;
user =
access = 1513647;
created = 14822;
data =
"ckeditor_auto_lang" = t;
"ckeditor_default" = t;
"ckeditor_lang" = en;
"ckeditor_show_toggle" = t;
"ckeditor_width" = "100%";
contact = 1;
;
我正在使用 Alamofire 进行 API 调用。
任何人都可以在这里帮助我实现这一目标吗?谢谢!
【问题讨论】:
您在使用 Alamofire 吗?斯威夫特 4? pod 'Alamofire' 这是我正在使用的 这似乎不是 Alamofire API 这只是 Alamofire @Vyacheslav 似乎他在自定义kNetworkManager
中使用它。
【参考方案1】:
由于您在 kNetworkManager
中使用 Alamofire,我建议您也使用 AlamofireObjectMapper 来摆脱解析响应并将其映射到模型的麻烦:
自动转换 JSON 响应的 Alamofire 扩展 使用 ObjectMapper 将数据转换为 swift 对象。
它很容易集成,您可以查看它的文档以熟悉如何做到这一点。
根据您提到的响应,可映射对象应类似于:
import ObjectMapper
class UserResponse: Mappable
var sessId: String?
var sessionName: String?
var tokenData: String?
var user: User?
required init?(map: Map)
func mapping(map: Map)
sessId <- map["sessid"]
sessionNamen <- map["session_name"]
tokenData <- map["tokenData"]
user <- map["user"]
class User: Mappable
var access: Int?
var created: Int?
required init?(map: Map)
func mapping(map: Map)
access <- map["day"]
created <- map["access"]
conditions <- map["created"]
data <- map["data"]
class UserData: Mappable
var ckEditorAutoLang: String?
var ckEditorDefault: String?
var ckEditorLang: String?
var ckEditorShowToggle: String?
var ckEditorWidth: String?
var contact: Int?
required init?(map: Map)
func mapping(map: Map)
ckEditorAutoLang <- map["ckeditor_auto_lang"]
ckEditorDefault <- map["ckeditor_default"]
ckEditorLang <- map["ckeditor_lang"]
ckEditorShowToggle <- map["ckeditor_show_toggle"]
ckEditorWidth <- map["ckeditor_width"]
contact <- map["contact"]
另外,如果你使用的是 Swift 4,你可能想看看Codable
,它应该会让你的生活更轻松!
【讨论】:
那么,对于每个类 API 调用,我需要创建模型类吗? 你如何将这个 web 服务响应传递给模型类,我没有看到你的代码 虽然,我这样做是在打印错误 kNetworkManager.executePostRequest(urlString: kAppManualLoginURL, params:paramDict, requestVC: self,completionHandler: (responseObject: DataResponse如果你使用 Alamofire 那么。使用这个常用方法
//MARK:- Public Method
/**
* Initiates HTTPS or HTTP request over |kHTTPMethod| method and
returns call back in success and failure block.
*
* @param serviceName name of the service
* @param method method type like Get and Post
* @param postData parameters
* @param responeBlock call back in block
*/
func requestApi(serviceName: String, method: kHTTPMethod, postData: Dictionary<String, Any>, withProgressHUD showProgress: Bool, completionClosure:@escaping (_ result: Any?, _ error: Error?, _ errorType: ErrorType, _ statusCode: NSNumber?) -> ()) -> Void
if NetworkReachabilityManager()?.isReachable == true
if showProgress
showProgressHUD()
let headers = getHeaderWithAPIName(serviceName: serviceName)
let serviceUrl = getServiceUrl(string: serviceName)
let params = getPrintableParamsFromJson(postData: postData)
print_debug(items: "Connecting to Host with URL \(kBASEURL)\(serviceName) with parameters: \(params)")
print_debug(items: "###### \(postData) ######")
//NSAssert Statements
assert(method != .GET || method != .POST, "kHTTPMethod should be one of kHTTPMethodGET|kHTTPMethodPOST|kHTTPMethodPOSTMultiPart.");
switch method
case .GET:
Alamofire.request(serviceUrl, method: .get, parameters: postData, encoding: URLEncoding.default, headers: headers).responseJSON(completionHandler:
(DataResponse) in
SVProgressHUD.dismiss()
switch DataResponse.result
case .success(let JSON):
print_debug_fake(items: "Success with JSON: \(JSON)")
print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
case .failure(let error):
print_debug(items: "json error: \(error.localizedDescription)")
if error.localizedDescription == "cancelled"
completionClosure(nil, error, .requestCancelled, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
else
completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
)
case .POST:
Alamofire.request(serviceUrl, method: .post, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler:
(DataResponse) in
SVProgressHUD.dismiss()
switch DataResponse.result
case .success(let JSON):
print_debug_fake(items: "Success with JSON: \(JSON)")
print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
case .failure(let error):
print_debug(items: "json error: \(error.localizedDescription)")
completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
)
case .PUT:
Alamofire.request(serviceUrl, method: .put, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler:
(DataResponse) in
SVProgressHUD.dismiss()
switch DataResponse.result
case .success(let JSON):
print_debug_fake(items: "Success with JSON: \(JSON)")
print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
case .failure(let error):
print_debug(items: "json error: \(error.localizedDescription)")
completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
)
case .PATCH:
Alamofire.request(serviceUrl, method: .patch, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler:
(DataResponse) in
SVProgressHUD.dismiss()
switch DataResponse.result
case .success(let JSON):
print_debug_fake(items: "Success with JSON: \(JSON)")
print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
case .failure(let error):
print_debug(items: "json error: \(error.localizedDescription)")
completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
)
case .DELETE:
Alamofire.request(serviceUrl, method: .delete, parameters: postData, encoding: URLEncoding.default, headers: headers).responseJSON(completionHandler:
(DataResponse) in
SVProgressHUD.dismiss()
switch DataResponse.result
case .success(let JSON):
print_debug_fake(items: "Success with JSON: \(JSON)")
print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
case .failure(let error):
print_debug(items: "json error: \(error.localizedDescription)")
completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
)
else
SVProgressHUD.dismiss()
completionClosure(nil, nil, .noNetwork, nil)
请根据你的方法调整这个方法,因为我是直接在我的网络公共类中复制这个方法
【讨论】:
以上是关于如何在 Swift 3 中为来自 web 服务的 Json 响应创建模型类的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中为 Radio Live Streaming 服务实现 HLS
如何在 iOS 中为 Swift 3/4 移除 UIPageViewController 弹跳效果