Swift 中的 Alamofire 和 ObjectMapper 到 TableView
Alamofire and ObjectMapper to TableView in Swift
我是 swift 的新手,正在尝试从 api 中获取 json 并将其显示给 UITableView,但它不会显示。
这是json:
{
"success": true,
"user_id": "somestringhere",
"devices": [
{
"id": "somestringhere",
"source": "somestringhere",
"source_text": "somestringhere",
"logo_url": "somestringhere",
"is_connected": "0"
},
{
用于映射 json 数据:
import Foundation
import ObjectMapper
class Devices: Mappable {
required init?(map: Map) {
}
func mapping(map: Map) {
id<-map["id"]
source<-map["source"]
sourceText<-map["source_text"]
logo<-map["logo_url"]
isConnected<-map["is_connected"]
}
var id : String?
var source : String?
var sourceText : String?
var logo : String?
var isConnected : Bool?
}
我的控制器:
import Foundation
import UIKit
import SwiftyJSON
import Alamofire
import ObjectMapper
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var devices : [Devices]?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(HomeTableViewCell.nib(), forCellReuseIdentifier: HomeTableViewCell.identifier)
tableView.delegate = self
tableView.dataSource = self
loadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return devices?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: HomeTableViewCell.identifier, for: indexPath) as! HomeTableViewCell
cell.setup(title: "\(devices?[indexPath.row].sourceText)", iconLink: "\(devices?[indexPath.row].logo)")
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func loadData(){
let base = Config().base
let endPoint = Config.EndPoint()
let patientId = User().id
let url = base + endPoint.showDevices
let header: HTTPHeaders = [
"Content-Type": "application/json",
]
let params: Parameters = [
"patient_id" : patientId
]
let code = Code(id: id)
AF.request(url, method: .get, parameters: params, encoding: URLEncoding.default, headers:header).validate()
.response{ (response) in
switch response.result {
case .success(let value):
let json = JSON(value)
self.devices = Mapper<Devices>().mapArray(JSONString: json.rawString()!)
self.tableView.reloadData()
case .failure(let error):
print(error)
}
}
}
}
我尝试在 Mapper 之后打印设备变量
self.devices = Mapper<PatientDevices>().mapArray(JSONString: json.rawString()!)
print(self.devices)
给我看
Optional([ProjectName.Devices])
我尝试打印 json 响应数据并成功请求,但我无法将其添加到表视图中。
我应该怎么做才能解决这个问题?
我不知道我做错了什么。
首先——一如既往——因为 Swift 4 个库,如 ObjectMapper
和 SwiftyJSON
已经过时,取而代之的是 built-in,高效 Codable
协议。避免推荐那些过时库的教程。
关于您的错误,您忽略了根对象,具有键 success
、user_id
和 devices
.
的对象
这是一个使用Decodable
的解决方案
删除 SwiftyJSON
和 ObjectMapper
将结构替换为
struct Root : Decodable {
let success : Bool
let userId : String
let devices : [Device]
}
struct Device : Decodable {
let id : String
let source : String
let sourceText : String
let logoUrl : URL
let isConnected : String // this value is String, not Bool
}
将loadData
替换为
func loadData(){
let base = Config().base
let endPoint = Config.EndPoint()
let patientId = User().id
let url = base + endPoint.showDevices
let header: HTTPHeaders = [
"Content-Type": "application/json",
]
let params: Parameters = [
"patient_id" : patientId
]
let code = Code(id: id)
AF.request(url, parameters: params, headers:header).validate()
.responseData { (response) in
switch response.result {
case .success(let data):
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self, from: data)
self.devices = result.devices
self.tableView.reloadData()
} catch { print(error) }
case .failure(let error):
print(error)
}
}
}
Alamofire 响应 returns 原始数据和 keyDecodingStrategy
将 snake_cased 键转换为 camelCased 结构成员和 logoUrl
被解码为 URL
最后将数据源数组重命名为
var devices = [Device]()
并删除devices
之后的所有问号
你错过了主要对象。添加此 class 除了您的设备 class。
import Foundation
import ObjectMapper
class Response: Mappable {
required init?(map: Map) {
}
func mapping(map: Map) {
success<-map["success"]
user_id<-map["user_id"]
devices<-map["devices"]
}
var success : Bool?
var user_id : String?
var devices: [Device]?
}
同时创建一个新变量来映射主对象
var response: Response?
并改变
self.devices = Mapper<Devices>().mapArray(JSONString: json.rawString()!)
到
self.response = Mapper<Response>().map(JSONString: json.rawString()!)
self.devices = self.response.devices
我是 swift 的新手,正在尝试从 api 中获取 json 并将其显示给 UITableView,但它不会显示。
这是json:
{
"success": true,
"user_id": "somestringhere",
"devices": [
{
"id": "somestringhere",
"source": "somestringhere",
"source_text": "somestringhere",
"logo_url": "somestringhere",
"is_connected": "0"
},
{
用于映射 json 数据:
import Foundation
import ObjectMapper
class Devices: Mappable {
required init?(map: Map) {
}
func mapping(map: Map) {
id<-map["id"]
source<-map["source"]
sourceText<-map["source_text"]
logo<-map["logo_url"]
isConnected<-map["is_connected"]
}
var id : String?
var source : String?
var sourceText : String?
var logo : String?
var isConnected : Bool?
}
我的控制器:
import Foundation
import UIKit
import SwiftyJSON
import Alamofire
import ObjectMapper
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var devices : [Devices]?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(HomeTableViewCell.nib(), forCellReuseIdentifier: HomeTableViewCell.identifier)
tableView.delegate = self
tableView.dataSource = self
loadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return devices?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: HomeTableViewCell.identifier, for: indexPath) as! HomeTableViewCell
cell.setup(title: "\(devices?[indexPath.row].sourceText)", iconLink: "\(devices?[indexPath.row].logo)")
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func loadData(){
let base = Config().base
let endPoint = Config.EndPoint()
let patientId = User().id
let url = base + endPoint.showDevices
let header: HTTPHeaders = [
"Content-Type": "application/json",
]
let params: Parameters = [
"patient_id" : patientId
]
let code = Code(id: id)
AF.request(url, method: .get, parameters: params, encoding: URLEncoding.default, headers:header).validate()
.response{ (response) in
switch response.result {
case .success(let value):
let json = JSON(value)
self.devices = Mapper<Devices>().mapArray(JSONString: json.rawString()!)
self.tableView.reloadData()
case .failure(let error):
print(error)
}
}
}
}
我尝试在 Mapper 之后打印设备变量
self.devices = Mapper<PatientDevices>().mapArray(JSONString: json.rawString()!)
print(self.devices)
给我看
Optional([ProjectName.Devices])
我尝试打印 json 响应数据并成功请求,但我无法将其添加到表视图中。 我应该怎么做才能解决这个问题? 我不知道我做错了什么。
首先——一如既往——因为 Swift 4 个库,如 ObjectMapper
和 SwiftyJSON
已经过时,取而代之的是 built-in,高效 Codable
协议。避免推荐那些过时库的教程。
关于您的错误,您忽略了根对象,具有键 success
、user_id
和 devices
.
这是一个使用Decodable
删除
SwiftyJSON
和ObjectMapper
将结构替换为
struct Root : Decodable { let success : Bool let userId : String let devices : [Device] } struct Device : Decodable { let id : String let source : String let sourceText : String let logoUrl : URL let isConnected : String // this value is String, not Bool }
将
loadData
替换为func loadData(){ let base = Config().base let endPoint = Config.EndPoint() let patientId = User().id let url = base + endPoint.showDevices let header: HTTPHeaders = [ "Content-Type": "application/json", ] let params: Parameters = [ "patient_id" : patientId ] let code = Code(id: id) AF.request(url, parameters: params, headers:header).validate() .responseData { (response) in switch response.result { case .success(let data): do { let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase let result = try decoder.decode(Root.self, from: data) self.devices = result.devices self.tableView.reloadData() } catch { print(error) } case .failure(let error): print(error) } } }
Alamofire 响应 returns 原始数据和
keyDecodingStrategy
将 snake_cased 键转换为 camelCased 结构成员和logoUrl
被解码为URL
最后将数据源数组重命名为
var devices = [Device]()
并删除
之后的所有问号devices
你错过了主要对象。添加此 class 除了您的设备 class。
import Foundation
import ObjectMapper
class Response: Mappable {
required init?(map: Map) {
}
func mapping(map: Map) {
success<-map["success"]
user_id<-map["user_id"]
devices<-map["devices"]
}
var success : Bool?
var user_id : String?
var devices: [Device]?
}
同时创建一个新变量来映射主对象
var response: Response?
并改变
self.devices = Mapper<Devices>().mapArray(JSONString: json.rawString()!)
到
self.response = Mapper<Response>().map(JSONString: json.rawString()!)
self.devices = self.response.devices