我有一个API供我的用户登录数据库。我使用以下代码将凭据发送到API,如果它们有效,我将获得有关用户信息的一些JSON类型数据。否则我得到一个字符串,说用户名或密码错误。 这是我的HTTTP Post请求:
let url = URL(string: "http://128.199.199.17:3000/api/login")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "email=22222@gmail.com&password=123456"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("\(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString!)")
}
task.resume()
它工作正常,我在控制台中获得以下信息:
{
"user_id": 2,
"email": "22222@gmail.com",
"password": "123456",
"user_name": "number 2 name",
"full_name": "danial kosarifar",
"sex": "male",
"height": 0,
"weight": 0,
"number_of_meal_per_day": 3,
"water_amount": 0,
"calories": 0,
"number_of_hours_to_sleep_per_day": 3,
"createdAt": "2017-11-14T17:23:31.000Z",
"updatedAt": "2017-11-14T17:25:37.000Z"
}
我还创建了一个可解码的结构:
struct User : Decodable {
let user_id : Int
let email : String
let password : String
let username : String
}
我的问题不是将数据解码为字符串,而是如何解码它们,以便我可以将它们放入我已经定义的结构中。我对这个话题完全不熟悉,如果我的问题太多初学者,请耐心等待。 谢谢
答案 0 :(得分:3)
Swift 4:
最好将struct
创建为Codable
,如下所示
struct User:Codable { //Because enum CodingKeys: String, CodingKey {
let userID : Int
let email : String
let password : String
let userName : String
let fullName:String
let sex:String
let height:Int
let weight:Int
let numberOfMealPerDay:Int
let waterAmount:Int
let calories:Int
let numberOfHoursToSleppPerDay:Int
let createdAt:String
let updatedAt:String
enum CodingKeys: String, CodingKey {
case userID = "user_id"
case email
case password
case userName = "user_name"
case fullName = "full_name"
case sex
case height
case weight
case numberOfMealPerDay = "number_of_meal_per_day"
case waterAmount = "water_amount"
case calories
case numberOfHoursToSleppPerDay = "number_of_hours_to_sleep_per_day"
case createdAt
case updatedAt
}
}
使用JSONDecoder
:
然后可以使用data
解析closure
task
内的回复数据JSONDecoder
。在此,user
是class
变量。即,var user:User?
if let json = try? JSONDecoder().decode(User.self, from: data!){
self.user = json
}
注意:为了更好地理解,这是关于swift 4中JSON解析的video系列
答案 1 :(得分:1)
您可以将自定义初始化程序添加到用户结构中,该结构将json数据作为参数并将其抛出。您还需要创建一个自定义日期格式化程序来解析日期(您需要包含毫秒数)。请注意,如果您的json响应可能不包含某些键/值,则需要将该属性设置为可选:
因此,对于日期格式化程序,您可以使用此answer中的自定义日期格式化程序:
extension Formatter {
static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
return formatter
}()
}
您的用户结构应如下所示:
struct User: Codable {
let id: Int
let email: String
let password: String
let userName: String
let fullName: String
let sex: String
let height: Int
let weight: Int
let mealsPerDay: Int
let waterAmount: Int
let calories: Int
let hoursToSleepPerDay: Int
let createdAt: Date
let updatedAt: Date
// you can provide different keys to your user struct properties
private enum CodingKeys: String, CodingKey {
case id = "user_id", email, password, userName = "user_name", fullName = "full_name", sex, height, weight, mealsPerDay = "number_of_meal_per_day", waterAmount = "water_amount", calories, hoursToSleepPerDay = "number_of_hours_to_sleep_per_day", createdAt, updatedAt
}
// custom initializer that takes the json data and throws in case of error
init(data: Data) throws {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(Formatter.iso8601)
self = try decoder.decode(User.self, from: data)
}
}
用法:
let data = Data("""
{
"user_id": 2,
"email": "22222@gmail.com",
"password": "123456",
"user_name": "number 2 name",
"full_name": "danial kosarifar",
"sex": "male",
"height": 0,
"weight": 0,
"number_of_meal_per_day": 3,
"water_amount": 0,
"calories": 0,
"number_of_hours_to_sleep_per_day": 3,
"createdAt": "2017-11-14T17:23:31.000Z",
"updatedAt": "2017-11-14T17:25:37.000Z"
}
""".utf8)
do {
let user = try User(data: data)
print(user) // User(id: 2, email: "22222@gmail.com", password: "123456", userName: "number 2 name", fullName: "danial kosarifar", sex: "male", height: 0, weight: 0, mealsPerDay: 3, waterAmount: 0, calories: 0, hoursToSleepPerDay: 3, createdAt: 2017-11-14 17:23:31 +0000, updatedAt: 2017-11-14 17:25:37 +0000)\n"
} catch {
print(error)
}