iOS App 接收格式正确的 JSON 但仍返回不是以数组或对象开头

Posted

技术标签:

【中文标题】iOS App 接收格式正确的 JSON 但仍返回不是以数组或对象开头【英文标题】:iOS App recieving correctly-formatted JSON but still returning as not starting with array or object 【发布时间】:2016-10-22 16:29:27 【问题描述】:

所以基本上我的服务器上有一个登录脚本,它根据用户凭据是正确还是错误返回结果,并且我有一个 ios 应用程序,它向该登录脚本发送数据以返回正确或错误的结果。

这是我的登录页面的相关部分,显示了返回码($userDetails 是正确或错误凭据的 TRUE 或 FALSE 检查):

$userDetails = $dao->getUserDetailsWithHashedPassword($email,$password);
if($userDetails===TRUE) 
    $returnValue["status"] = "Success";
    $returnValue["message"] = "User logged in !";
    echo json_encode($returnValue);
 else 
    $returnValue["status"] = "error";
    $returnValue["message"] = "User not found";
    echo json_encode($returnValue);

如果有人需要查看 getUserDetailsWithHashedPassword() 的作用,click here

使用 Postman 测试 HTTP POST,一切正常,当我在正文中发布 email@email.com 和 testpassword 并使用正确的 Content-Type (application/x-www-form-urlencoded) 时,我得到了正确的结果:

"status":"error","message":"User not found"

现在我的 iOS 应该用这段代码来解释这个:

@IBAction func loginButtonPressed(_ sender: AnyObject) 
        let userEmail = emailLoginField.text
        let userPassword = passwordLoginField.text
        // Check for empty fields
        if((userEmail?.isEmpty)! || (userPassword?.isEmpty)!)  
            // Display alert message
            displayMyAlertMessage(userMessage: "All fields are required");     
            return ;
        
        // Send user data to server side
        let myUrl = URL(string: "https://support.vincentsolutions.ca/userLogin.php");
        var request = URLRequest(url:myUrl!);
        request.httpMethod = "POST";
        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        let postString = "email=\(userEmail!)&password=\(userPassword!)";
        request.httpBody = postString.data(using: String.Encoding.utf8);

        URLSession.shared.dataTask(with: request, completionHandler:  (data:Data?, response:URLResponse?, error:Error?) -> Void in
            if error != nil 
                print ("error=\(error)")
                return
            
            do 
                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
                if let parseJSON = json 
                    var resultValue = parseJSON["status"] as? String
                    print("result: \(resultValue)")
                    var isUserLoggedIn:Bool = false;
                    if(resultValue=="Success") 
                        // Login is successful
                        UserDefaults.standard.set(true, forKey: "isUserLoggedIn");
                        UserDefaults.standard.synchronize();    
                        self.performSegue(withIdentifier: "loginSuccesful", sender: self)
                    
                    var messageToDisplay:String = parseJSON["message"] as! String!;
                    if(!isUserLoggedIn) 
                        messageToDisplay = parseJSON["message"] as! String!;
                    
                    DispatchQueue.main.async(execute: 
                        // Display alert message with confirmation.
                        var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.alert);

                        let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) action in
                            self.dismiss(animated: true, completion: nil);
                         
                        myAlert.addAction(okAction);
                        self.present(myAlert, animated: true, completion: nil);
                    );   
                  
             catch let error as NSError 
                print("An error occured: \(error)")
            
        ).resume()

现在当我从 iOS 应用程序运行代码时出现此错误:

发生错误:Error Domain=NSCocoaErrorDomain Code=3840 "JSON 文本 没有以数组或对象和允许片段的选项开头 设置。”

有人知道这里有什么问题吗?我尝试在 SO 和 Internet 上查找该错误,但找不到与我的情况相关的任何内容。

【问题讨论】:

【参考方案1】:

这是因为您从 URL 收到的响应可能不是正确的 JSON 格式。我会建议你做两件事-

    尝试 NSLog 数据和响应 试试这个

让 json = 试试 NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary

【讨论】:

嗯,我收到的回复是这样的:"status":"error","message":"User not found" 当我在link 使用 JSONLint 时,它表示使用 Postman 返回时响应的格式正确。这是否意味着响应是有效的,它可能与应用处理响应的方式? 另外 NSJSONReadingOptions 在 Swift 3 中似乎不起作用。说它是未定义的。 我可以使用options : .allowFragments 尝试您的解决方案,这似乎是正确的 Swift 3 语法,但现在我遇到了另一个错误:Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0 。” 终于成功了。这里和那里有一些问题,但 .allowFragments 使它起作用。谢谢!

以上是关于iOS App 接收格式正确的 JSON 但仍返回不是以数组或对象开头的主要内容,如果未能解决你的问题,请参考以下文章

后端如何接受json对象数据如何设置表头

在 Swift 3 中正确格式化 JSON 对象

后端返回值以json的格式返回,前端以json格式接收

设计一个java接口,接收json,并且将处理结果按json的格式返回

Java发送POST请求,参数为JSON格式,并接收返回JSON数据

C# webApi----H5_app后台制作--序列化的类无法接收Json格式的数据