【发布时间】:2017-02-07 17:01:08
【问题描述】:
我有一个服务器用于在我的应用程序中存储用户名和密码数据。在测试应用程序时,我使用 NSDefaults 将所有内容保存到本地设备,但现在应用程序已接近完全启动,我尝试将它们保存到服务器,因为这样对用户信息更安全。
当我将它保存到 NSDefaults 时,它的工作简单而短暂。但是,现在我正在尝试将数据发布到服务器并不断收到构建错误。我需要改变什么才能使它起作用?我是否不完全了解 POST 和 GET 的工作原理?谢谢。目前使用 Swift 2,不是我的选择,我更喜欢 3,但我的老板还不让我们更新它。
当前错误来自 POST USER DATA TO SERVER 部分,其中 xcode 声称 userNmeTxt 无法转换为 NSData。提前谢谢你。
编辑:第 87 行出现错误:“无法将 UITextField 类型的值转换为预期的参数类型 NSData!”
import UIKit
class UserNameViewController: AuthorizationViewController {
@IBOutlet weak var userNameTxt: UITextField!
@IBOutlet weak var continueBtn: UIButton!
var userModel: ProfileModel!
//MARK: - SYSTEMS METHODS
override func viewDidLoad() {
super.viewDidLoad()
userNameTxt.delegate = self
userNameTxt.autocapitalizationType = .Sentences
setEnabledButton()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBarHidden = false
self.navigationItem.leftBarButtonItem = getBackButton()
self.title = ""
}
override func viewWillDisappear(animated: Bool) {
self.navigationController?.navigationBarHidden = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
continueBtn.layer.cornerRadius = 10
}
override func popToRoot(sender:UIBarButtonItem){
self.navigationController!.popViewControllerAnimated(true)
}
//MARK: - CHECK FOR AVALABILITY
func setEnabledButton(){
if userNameTxt.text == "" {
continueBtn.backgroundColor = UIColor.lightGrayColor()
} else {
continueBtn.backgroundColor = UIColor(colorLiteralRed: 63.0/255.0, green: 220.0/255.0, blue: 236.0/255.0, alpha: 1.0)
}
continueBtn.userInteractionEnabled = userNameTxt.text != ""
}
//MARK: - POST USER DATA TO SERVER
func postData(url: String, params: Dictionary<String, String>, completionHandler: (data: NSData?, response: NSURLResponse?, error: NSError?) -> ()) {
// Indicate download
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
let url = NSURL(string: "myPlaceholderURLgoesHere")!
// print("URL: \(url)")
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
// Verify downloading data is allowed
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: [])
} catch let error as NSError {
print("Error in request post: \(error)")
request.HTTPBody = nil
} catch {
print("Catch all error: \(error)")
}
// Post the data
let task = session.dataTaskWithRequest(request) { data, response, error in
completionHandler(data: userNameTxt, response: userModel, error: error)
// Stop download indication
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
// Stop download indication
}
task.resume()
}
//MARK: - SEGUE
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toPassword"{
let controller = segue.destinationViewController as! PasswordViewController
controller.userModel = userModel
}
}
//MARK: - IB ACTIONS
@IBAction func continuePressed(sender: AnyObject) {
userModel.userNickName = userNameTxt.text!
performSegueWithIdentifier("toPassword", sender: self)
}
}
extension UserNameViewController: UITextFieldDelegate{
func textFieldDidEndEditing(textField: UITextField) {
self.setEnabledButton()
}
}
【问题讨论】:
-
如果您不知道,您可能需要考虑使用
NSUbiquitousKeyValueStore:developer.apple.com/library/content/documentation/Cocoa/… 将首选项存储在 iCloud Key-Value 存储中 -
首先,不要将密码存储在 NSUserdefaults 中,至少要单独加密。至少尝试保护用户的安全。此外,在服务器上存储凭据似乎很奇怪。当您注册帐户时,应存储凭据(使用凭据特定的盐进行加密保护:owasp.org/index.php/…)。当用户在设备上输入他们的凭据时,您应该点击 Web 服务来验证凭据,无需重新保存。
-
如果您为了方便而保存凭据,则应将其存储在钥匙串中。
标签: ios swift xcode post user-data