2015-08-04 22 views
9

Sto cercando di analizzare JSON, ma sempre questo errore:Come fare il parsing JSON a Swift utilizzando NSURLSession

type of expression is ambiguous without more context

Il mio codice è:

func jsonParser() { 

    let urlPath = "http://headers.jsontest.com/" 
    let endpoint = NSURL(string: urlPath) 
    let request = NSMutableURLRequest(URL:endpoint!) 

    let session = NSURLSession.sharedSession() 
    NSURLSession.sharedSession().dataTaskWithRequest(request){ (data, response, error) throws -> Void in 

     if error != nil { 
      print("Get Error") 
     }else{ 
      //var error:NSError? 
      do { 
       let json:AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as? NSDictionary 

      print(json) 

     } catch let error as NSError { 
      // error handling 
      print(error?.localizedDescription) 
     } 
     } 
    } 
    //task.resume() 
} 

Questo sta lavorando bene con fuori tentativo di cattura in Xcode 6.4 ma questo non funziona in Xcode 7.

risposta

27

Non dichiarare un tipo AnyObject per l'oggetto decodificato poiché si desidera che sia un NSDictionary e si sta eseguendo una conversione per farlo.

Inoltre, è preferibile utilizzare zero opzioni per NSJSONSerialization anziché random.

Nel mio esempio ho anche utilizzato un tipo di errore personalizzato solo per dimostrazione.

Nota: se si utilizza un tipo di errore personalizzato, è necessario includere anche un catch generico per essere esaustivo (in questo esempio, con un downcast semplice a NSError).

enum JSONError: String, ErrorType { 
    case NoData = "ERROR: no data" 
    case ConversionFailed = "ERROR: conversion from JSON failed" 
} 

func jsonParser() { 
    let urlPath = "http://headers.jsontest.com/" 
    guard let endpoint = NSURL(string: urlPath) else { 
     print("Error creating endpoint") 
     return 
    } 
    let request = NSMutableURLRequest(URL:endpoint) 
    NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in 
     do { 
      guard let data = data else { 
       throw JSONError.NoData 
      } 
      guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else { 
       throw JSONError.ConversionFailed 
      } 
      print(json) 
     } catch let error as JSONError { 
      print(error.rawValue) 
     } catch let error as NSError { 
      print(error.debugDescription) 
     } 
    }.resume() 
} 

Lo stesso con Swift 3.0.2:

enum JSONError: String, Error { 
    case NoData = "ERROR: no data" 
    case ConversionFailed = "ERROR: conversion from JSON failed" 
} 

func jsonParser() { 
    let urlPath = "http://headers.jsontest.com/" 
    guard let endpoint = URL(string: urlPath) else { 
     print("Error creating endpoint") 
     return 
    } 
    URLSession.shared.dataTask(with: endpoint) { (data, response, error) in 
     do { 
      guard let data = data else { 
       throw JSONError.NoData 
      } 
      guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary else { 
       throw JSONError.ConversionFailed 
      } 
      print(json) 
     } catch let error as JSONError { 
      print(error.rawValue) 
     } catch let error as NSError { 
      print(error.debugDescription) 
     } 
    }.resume() 
} 
3

Apple dichiara qui.

func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask 

Fix it:

NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in 
     // Your handle response here! 
} 

UPDATE:

func jsonParser() { 
    let urlPath = "http://headers.jsontest.com/" 
    let endpoint = NSURL(string: urlPath) 
    let request = NSMutableURLRequest(URL:endpoint!) 

    NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in 
     print(error) 
    }.resume() 
} 

RISULTATO:

Optional(Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSUnderlyingError=0x7f8873f148d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}, NSErrorFailingURLStringKey= http://headers.jsontest.com/ , NSErrorFailingURLKey= http://headers.jsontest.com/ , NSLocalizedDescription=The resource could not be loaded because the App >Transport Security policy requires the use of a secure connection.})

Spero che questo aiuti!

+0

Anch'io uso questo codice ma ottenendo errore "il tipo di espressione è ambiguo senza più contesto". – vipulk617

+0

Guarda il mio codice. Rimuovi 'getta' nel tuo codice. Per favore! –

+0

Ho rimosso i tiri ma ottenendo lo stesso errore. – vipulk617

-2

1) Effettuare classe ApiConnection al tuo progetto .. importazione Fondazione classe ApiConnection: NSObject {

class func postDataWithRequest(_ dicData:NSDictionary, completionHandler:@escaping (_ response:NSDictionary?,_ status:Bool)->Void) 
{ 
    let URL=Foundation.URL(string: Constant.API_URL) 
    let request=NSMutableURLRequest(url: URL!) 
    request.httpMethod="POST" 
    request.addValue(Constant.kApplicationJSON, forHTTPHeaderField:Constant.kContentType) 
    let data=try? JSONSerialization .data(withJSONObject: dicData, options: JSONSerialization.WritingOptions.prettyPrinted) 
    request.httpBody=data 

    //let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(Double(NSEC_PER_SEC)*5)) 
    //dispatch_after(dispatchTime, dispatch_get_main_queue()) { 
    let session = URLSession.shared.dataTask(with: request as URLRequest,completionHandler: { (data, response, error) in 
     if error==nil 
     { 
      DispatchQueue.main.async(execute: { 
       let dicResponse = try? JSONSerialization .jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary 
       completionHandler(dicResponse, error==nil) 
      }) 
     } 
     else 
     { 
      completionHandler(nil, error==nil) 
     } 
    }) 
    session.resume() 
    } 
} 
**********************************use this in your view controller**************** 

let dict : NSMutableDictionary = [:]; 

    dict["Your key"] = "your value" 
    dict["Your key"] = "your value" 
    dict["Your key"] = "your value" 

    ApiConnection.postDataWithRequest(dict) { (response, status) in 
     if(status){ 
      print(response); 
     else{ 
      print("failed webservice call"); 
     } 
    } 

************************************* Swift3.0 *************************************

 var objDic = [String: Any]() 
     let dic = NSMutableDictionary() 
     print(dic) 
     objDic["action"] = "" 
     objDic["product_id"] = self.peroductid 
     //   arrProduct .addObjects(from: objDic) as! Dictionary 
     print("\(objDic)") 


     Alamofire.request(Constant.Webservice_productinfo, 
          method: HTTPMethod.post, 
          parameters:objDic as? Parameters, 
          encoding: JSONEncoding.default, 
          headers: nil).responseJSON 


      { 
       (response:DataResponse<Any>) in 
       switch(response.result) 
       { 
       case .success(_): 
        if response.result.value != nil 
        { 
          let status = response2?.object(forKey: "status") as! String? 

         if status == "error"{} 

         //finding the status from response 
         var response2 = response.result.value as AnyObject? 
          self.response1 = response.result.value as! NSDictionary 
               let type = 
         (self.cartlistarray[0] as!NSDictionary)["base_image"] 
             cell.productname.text = (self.cartlistarray[0] as!NSDictionary)["name"] as? String 

    //Store the result value in swift 3.0 

    UserDefaults.standard.set(userDetail.value(forKey: "email") as? NSString, forKey: "email") 
     if(UserDefaults.standard.object(forKey:"email") == nil){} 
//did select row click the data pass into another view 
    let ProductListViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProductListViewController") as! ProductListViewController   
ProductListViewController.category_id = ((self.bannerarry[0] as? [String : String])?["cat_id"])! 

//or else callin from indexpath.row 

      item = ((cartlistarray[indexpath.row] as? NSDictionary)?.value(forKey:"product_id") as! String?)! 

estensione UIAlertController {

func showErrorAlert(strMesage:NSString,VC:Any) 
{ 
    let alert = UIAlertController(title: "Demo App", message: strMesage as String, preferredStyle: UIAlertControllerStyle.alert) 
    alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)) 
    (VC as AnyObject).present(alert, animated: true, completion: nil) 
} 

} estensione UILabel {

func setLabel(strTitle:String) 
{ 
    self.backgroundColor = UIColor.clear 
    self.textColor = UIColor.white 
    self.textAlignment = NSTextAlignment.left 
    self.font = UIFont(name: "Avenir-Light", size: 15.0) 
    self.font = UIFont.italicSystemFont(ofSize: 15) 
    self.text=strTitle 
} 

}

//image in to base 64 

let image = imageCamera.image 
      let imageData:NSData = UIImageJPEGRepresentation(image!, 1.0)!as NSData 
      imageconvert = imageData.base64EncodedString(options: .lineLength64Characters) 
      base64formate = imageconvert.trimmingCharacters(in:CharacterSet.whitespaces) 
      print(base64formate) 

print data into profle view 

    let imageurl:String! = SharedManager.sharedInstance().myMutableDict.value(forKey:"profileimg") as? String ?? "123" 
    let url = URL(string: imageurl) 

    DispatchQueue.global(qos: .userInitiated).async { 

     let imageData:NSData = NSData(contentsOf: url!)! 
     // When from background thread, UI needs to be updated on main_queue 
     DispatchQueue.main.async { 
      let image = UIImage(data: imageData as Data) 
      self.imageview.image = image 

     } 
    } 


       let actionSheetController: UIAlertController = UIAlertController(title: "Magento Extension App", message:response1?.object(forKey: "message") as? String, preferredStyle: .alert) 
          actionSheetController.addAction(UIAlertAction(title: "Ok", style: .default , handler:{ (UIAlertAction)in 
           print("Ok button click") 
          })) 
          self.present(actionSheetController, animated: true, completion: nil) 
     } 

       case .failure(_): 

        print("error: \(response.result.error)") // original 
        URL request 
        break 
       } 
     } 

*************** *********** objc ************************************** ************

NSDictionary *objDic1 = @{@"mode":@"loginUser", 
             @"email":[result 
objectForKey:@"email"], 
             @"password":@"", 
             }; 
      // With AFNetworking 
      AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 
      manager.requestSerializer = [AFJSONRequestSerializer serializer]; 
      [manager.requestSerializer setTimeoutInterval:100]; 

      // manager set 
      [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 

      [manager POST:WEBSERVICE_CALL_URL parameters:objDic1 progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable result) { 

       [SVProgressHUD dismiss]; 

       NSLog(@"This s my response %@",result); 
       NSLog(@"success!"); 

       if ([[result valueForKey:kStatus] isEqualToString:kOK]) 
       { 
       } 
        } 
        failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) 
       { 
}]; 
****************SDK LINK******************************************* 
https://github.com/AFNetworking/AFNetworking 

var userDetail = NSArray() 
           userDetail = self.response1.value(forKey: "userData") as! NSArray 
           print(userDetail) 

self.tmpDic = userDetail[0] as! NSDictionary 
             print(self.tmpDic) 

             var optionsdic = NSDictionary() 
             optionsdic = self.tmpDic.value(forKey:"options") as! NSDictionary 
             print(optionsdic) 

             self.arrayOfKeys = optionsdic.allKeys as NSArray 
             print(self.arrayOfKeys) 
             if (self.arrayOfKeys.contains("color")) 
             { 
              print("color") 

              self.colorarray = optionsdic.value(forKey:"color") as! NSArray 
              print(self.colorarray.count) 

              for index in 0..<self.colorarray.count 
              { 
               var dic = NSDictionary() 
               dic = self.colorarray .object(at: index) as! NSDictionary 
               self.colorarrayobject .add(dic) 
               print(dic) 
              } 
              print(self.colorarrayobject) 

             } 
             else { 

              var defaultarray = NSArray() 
              defaultarray = optionsdic.value(forKey:"default") as! NSArray 
              print(defaultarray) 

              self.element0array = defaultarray[0] as! NSArray 
              print(self.element0array) 


              self.dic = self.element0array[0] as! NSDictionary 
              print(dic) 

              self.arr5 = self.dic .value(forKey: "values") as! NSArray 
              print(self.arr5) 

              for iteams in 0..<self.arr5.count 
              { 

               var type = String() 
               type = ((self.arr5[iteams]as! NSDictionary)["label"]! as? String)! 
               self.configeresizeaarray.append(type) 
              } 

              print("default") 

             } 

            } 
            self.imagearray = self.array[0] as! NSArray 

            for items in 0..<self.imagearray.count 
            { 
             var type = String() 
             type = ((self.imagearray [items]as! NSDictionary)["image"]! as? String)! 
             self.cell0imagearray.append(type) 
            } 
            self.count = self.imagearray.count as Int 
            self.configurePageControl() 
            self.tableView.reloadData() 
           } 
           else 
           { 

           } 

          } 
          else 
          { 

          } 
-1

Ecco il modo più semplice per analizzare JSON utilizzando NSUrlSession.,

let PARAMS = "{\"params1\":\"%@\",\"Params2\":\"%@\",\"params3\":\"%@\"}" 
let URL = "your url here" 

sul pulsante di invio scrivere questo codice.,

let urlStr = String(format: "%@",URL) 
let jsonString = String(format:PARAMS, params1value,params2value,params3value) 
// Encode your data here 
let jsonData = jsonString.data(using:.utf8) 
var request = URLRequest(url: URL(string: urlStr)!) 
request.setValue("application/json", forHTTPHeaderField: "Content-Type") 
request.setValue("application/json", forHTTPHeaderField: "Accept") 
//set your method type here 
request.httpMethod = "POST" 
request.httpBody = jsonData 
let configuration = URLSessionConfiguration.default 
// create a session here 
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) 
    let task = session.dataTask(with: request) {(data , response, error) in 
     if(error != nil){ 
      print("Error \(String(describing: error))") 
     } 
else { 
      do { 
       let fetchedDataDictionary = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary 
       print(fetchedDataDictionary!) 
       let message = fetchedDataDictionary?["response key here"] as! String 
       if message == "your response string" { 
        print(message) 

       } 
       else { 
        self.dataArray = (fetchedDataDictionary?["data"] as! NSArray) 
       } 
      } 
      catch let error as NSError { 
       print(error.debugDescription) 
      } 
     } 
    } 
    task.resume() 
+0

posso sapere i motivi dei voti bassi? –