Почему я получаю сообщение об ошибке ‘Domain = NSCocoaErrorDomain Code = 3840 «Нет значения». userInfo={NSDebugDescription= Нет значения.}’?

#ios #mysql #json #swift #xcode

#iOS #mysql #json #swift #xcode

Вопрос:

Я новичок в разработке Swift и iOS, но я пытаюсь загрузить и проанализировать данные, которые хранятся в базе данных MySQL.

Я продолжаю получать ошибку:

Domain = NSCocoaErrorDomain Code = 3840 «Нет значения». userInfo={NSDebugDescription= Нет значения.}

Я опубликовал свой код ниже, но я не думаю, что проблема заключается в функции parseJSON, а в фактической загрузке данных, поскольку, когда я печатаю «данные», они возвращают «<>».

Вот мой код:

 //properties

weak var delegate: HomeModelProtocal!

var data : NSMutableData = NSMutableData()

let urlPath: String = "http://localhost/service.php" //this will be changed to the path where service.php lives

// Function to download the incoming JSON data
func downloadItems(){
    let url: URL = URL(string: urlPath)!
    var session: URLSession!
    let configuration = URLSessionConfiguration.default


    session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)

    let task = session.dataTask(with: url)

    task.resume()
}

func urlSession(_ session: URLSession, task: URLSessionDataTask, didCompleteWithError error: Error?) {
    self.data.append(data as Data)
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    if error != nil{
        print("Failed to download data")
    }else{
        print("Data downloaded")
        print(data)
        self.parseJSON()
    }
}

func parseJSON(){

    var jsonResult: NSMutableArray = NSMutableArray()

    do{
        jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options: []) as! NSMutableArray
    } catch let error as NSError {
        print("**** sake its happened again (error)")
    }

    var jsonElement: NSDictionary = NSDictionary()
    let locations: NSMutableArray = NSMutableArray()

    for i in 0 ..< jsonResult.count{
        jsonElement = jsonResult[i] as! NSDictionary

        let location = LocationModel()

        //the following insures none of the JsonElement values are nil through optional binding
        if let exerciseName = jsonElement["stationName"] as? String,
            let bodyPart = jsonElement["buildYear"] as? String
        {
            print(exerciseName, bodyPart)
            location.exerciseName = exerciseName
            location.bodyPart = bodyPart

        }

        locations.add(location)

    }

    DispatchQueue.main.async(execute: { () -> Void in

        self.delegate.itemsDownloaded(items:locations)

    })
}
  

Комментарии:

1. Возможно, ответ пустой? Что вы print(data) показываете?

2. попробуйте сделать это в postman или где-нибудь еще и проверьте, действительно ли там что-то есть

3. Я попытался распечатать данные, и они возвращают <> Когда я просматриваю URL-адрес, который я использую, я получаю следующее: ‘[ { «Exercise_Id»: «1», «Exercise_Name»: «Скручивание штанги», «Body_Part»: «Руки» }, ‘

Ответ №1:

Особенно плохо в вашем коде:

 //This method is not being called...
func urlSession(_ session: URLSession, task: URLSessionDataTask, didCompleteWithError error: Error?) {
    self.data.append(data as Data) //<-This line adding self.data to self.data
}
  

Не существует urlSession(_:task:didCompleteWithError:) метода, который принимает URLSessionDataTask в качестве второго параметра. Таким образом, этот метод никогда не будет вызван.

И внутри метода self.data добавляется self.data , поэтому, даже если метод вызывается, self.data он все равно остается пустым…

Вместо этого вам нужно реализовать этот метод:

 func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    self.data.append(data)
}
  

Но если вы не хотите ничего делать, кроме накопления полученных данных, вам не нужно использовать делегатов.

И вы используете принудительное приведение в своем parseJSON() методе:

     jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options: []) as! NSMutableArray
  

без указания .mutableContainers опции. Это также приведет к сбою вашего приложения.

И ваш код использует слишком много NSSomethings .


Исправив все подобные вещи, вы можете получить что-то вроде этого:

 //properties

weak var delegate: HomeModelProtocal!

let urlPath: String =  "http://localhost/service.php" //this will be changed to the path where service.php lives

// Function to download the incoming JSON data
func downloadItems() {
    let url: URL = URL(string: urlPath)!
    let session = URLSession.shared

    let task = session.dataTask(with: url) {data, response, error in
        if let error = error {
            print("Failed to download data: (error)")
        } else if let data = data {
            print("Data downloaded")
            print(data as NSData)
            //print(String(data: data, encoding: .utf8))
            self.parseJSON(data: data)
        } else {
            print("Something is wrong...")
        }
    }

    task.resume()
}

func parseJSON(data: Data){

    do {
        if let jsonResult = try JSONSerialization.jsonObject(with: data) as? [[String: AnyObject]] {

            var locations: [LocationModel] = []

            for jsonElement in jsonResult {
                let location = LocationModel()

                //the following insures none of the JsonElement values are nil through optional binding
                if let exerciseName = jsonElement["stationName"] as? String,
                    let bodyPart = jsonElement["buildYear"] as? String
                {
                    print(exerciseName, bodyPart)
                    location.exerciseName = exerciseName
                    location.bodyPart = bodyPart

                }

                locations.append(location)

                DispatchQueue.main.async {
                    self.delegate.itemsDownloaded(items: locations)
                }
            }
        } else {
            print("bad JSON")
        }
    } catch let error as NSError {
        print("**** sake its happened again (error)")
    }
}
  

Комментарии:

1. Большое вам спасибо за помощь в решении моей проблемы, это исправило ее отлично!