2017-10-18 9 views
4

Je suis en train d'écrire une requête POST à ​​mon serveur local, c'est ma fonction:Swift 4 décodables: Les données annoncées n'a pas été JSON valide

@IBAction func postButtonAction(_ sender: UIButton) { 

    guard let url = URL(string:"http://localhost:443/api/message") else {return} 
    var request = URLRequest(url: url) 
    request.httpMethod = "POST" 
    request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
    print("POSTED") 

    let date : Date = Date() 
    let dateFormatter = DateFormatter() 
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 
    let dateTime = dateFormatter.string(from: date) 

    let newPost = MessageForPost(message: "Hi", timestamp: dateTime, latitude: "1.1", longitude: "2.2") 
    let newData = DataForPost(message: newPost) 
    let newPackage = PackageForPost(data: newData) 

    do { 
     let jsonBody = try JSONEncoder().encode(newPackage) 
     request.httpBody = jsonBody 
     print("jsonBody:",jsonBody) 
     let jsonBodyString = String(data: jsonBody, encoding: .utf8) 
     print("JSON String : ", jsonBodyString!) 
    } catch let err { 
     print("jsonBody Error: ",err) 
    } 

    let session = URLSession.shared 
    let task = session.dataTask(with: request){ (data,response,err) in 

     guard let data = data else {return} 

     do{ 
      let sendPost = try JSONDecoder().decode(PackageForPost.self, from: data) 
      print("DATA:\(data)") 
     }catch let err{ 

      print("Session Error: ",err) 
     } 
    } 
    task.resume() 
} 

Ce sont les struct en utilisant ici:

struct PackageForPost:Encodable, Decodable{ 
    let data: DataForPost 
} 

struct DataForPost:Encodable, Decodable{ 
    let message: MessageForPost 
} 

struct MessageForPost:Codable { 
    let message: String 
    let timestamp: String 
    let latitude: String 
    let longitude: String 
} 

Et il a pu imprimer

JSON String : {"data":{"message":{"message":"Hi","timestamp":"2017-10-18 00:50:13","latitude":"1.1","longitude":"2.2"}}} 

Mais il continue d'afficher cette erreur:

Session Error: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))

Pourquoi n'est-ce pas un JSON valide ???

API Voici mon serveur POST document de demande:

POST 
/api/message 

{ 
    data: { 
     message: { 

      message: “Hey, a new message!”, 
      timestamp: 2017-09-10 10:22:33, 
      latitude: 62.233589156441724, 
      longitude: 25.735066461654696 
     } 
    } 
} 

Je l'ai fait pas mal de googler, mais je suis coincé ici depuis très longtemps! Toute aide appréciée!

+0

Je vous ai couru code de décodage de base dans Playground et ça fonctionne bien. Je pourrais suggérer que vous décodiez 'Data' en' String' et que vous l'imprimiez juste pour vous assurer que vous savez exactement ce que vous essayez de décoder, parce que s'il commence par 'POST', alors c'est votre problème – MadProgrammer

+0

Imprimez les données reçues: 'print (données en tant que NSData)' avant la ligne 'decode'. Le premier octet doit être '7B'. Le message d'erreur dit, ce n'est pas le cas. – vadian

+2

Ce que @vadian a dit. Vous avez formulé la question comme si vous pensiez que quelque chose ne va pas dans la façon dont vous construisez les données. Il n'y a pas. Le message d'erreur que vous obtenez est en fait celui de * décoder * une chaîne JSON en objets Swift. Quand il dit que le texte doit commencer par un tableau ou un objet, cela signifie que la chaîne doit commencer par '[' ou '{' respectivement. Probablement la réponse du serveur n'est pas JSON – JeremyP

Répondre

0

Il était simple .. j'ai eu le même genre de problème ..

Regardez votre Struct est codage et de décodage Horodatage, latitude et la longitude que les chaînes et JSON est en double ou de type flottant.

struct MessageForPost:Codable { 
    let message: String 
    let timestamp: String 
    let latitude: String 
    let longitude: String 
} 

Et ici Json

{ 
    data: { 
     message: { 

      message: “Hey, a new message!”, 
      timestamp: 2017-09-10 10:22:33, 
      latitude: 62.233589156441724, 
      longitude: 25.735066461654696 
     } 
    } 
} 

.... Je l'ai fixé à ma fin et ... ça a marché ..

Edité utilisent le même type de données ..