Correctly Parsing JSON in Swift 3

前端 未结 9 980
甜味超标
甜味超标 2020-11-21 07:00

I\'m trying to fetch a JSON response and store the results in a variable. I\'ve had versions of this code work in previous releases of Swift, until the GM version of Xcode 8

9条回答
  •  闹比i
    闹比i (楼主)
    2020-11-21 07:59

    Updated the isConnectToNetwork-Function afterwards, thanks to this post.

    I wrote an extra method for it:

    import SystemConfiguration
    
    func loadingJSON(_ link:String, postString:String, completionHandler: @escaping (_ JSONObject: AnyObject) -> ()) {
    
        if(isConnectedToNetwork() == false){
            completionHandler("-1" as AnyObject)
            return
        }
    
        let request = NSMutableURLRequest(url: URL(string: link)!)
        request.httpMethod = "POST"
        request.httpBody = postString.data(using: String.Encoding.utf8)
    
        let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
            guard error == nil && data != nil else { // check for fundamental networking error
                print("error=\(error)")
                return
            }
    
            if let httpStatus = response as? HTTPURLResponse , httpStatus.statusCode != 200 { // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(response)")
            }
            //JSON successfull
            do {
                let parseJSON = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
                DispatchQueue.main.async(execute: {
                    completionHandler(parseJSON as AnyObject)
                });
            } catch let error as NSError {
                print("Failed to load: \(error.localizedDescription)")
            }
        }
        task.resume()
    }
    
    func isConnectedToNetwork() -> Bool {
    
        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
    
        let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
                SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
            }
        }
    
        var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
        if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
            return false
        }
    
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        let ret = (isReachable && !needsConnection)
    
        return ret
    }
    

    So now you can easily call this in your app wherever you want

    loadingJSON("yourDomain.com/login.php", postString:"email=\(userEmail!)&password=\(password!)") { parseJSON in
    
        if(String(describing: parseJSON) == "-1"){
            print("No Internet")
        } else {
    
        if let loginSuccessfull = parseJSON["loginSuccessfull"] as? Bool {
            //... do stuff
        }
    }
    

提交回复
热议问题