简体   繁体   中英

Method Always Returning Nil

I'm trying to get JSON data from the fitbit servers and print it. When I run the first function I ALWAYS get nil. However when I run the second function it prints the data correctly. I'm guessing it has something to do with the time it takes for the iPhone to grab the JSON from the server, but am completely clueless on how to solve it. My end goal is to return the data but I cannot obviously do it from a completion handler.

static func getFitbitData(resource: ResourcePath, date: Date) -> Int? {
        var rawData: NSData?
        let request = oauth.request(forURL: NSURL(string: "https://api.fitbit.com/1/user/-/\(resource.rawValue)/date/\(date.toString())/1d.json")!)
        let task = oauth.session.dataTaskWithRequest(request) { data, response, error in
            if error != nil {
                print("[ERROR] An error occured during request: \(error)")
            }
            else {
                print("[SUCCESS] Data retrieved successfully")
                rawData = data!
            }
        }
        task.resume()
        return ParsingEngine.parseFitbitData(ResourcePath.calories, data: rawData!)
    }



static func getFitbitData(resource: ResourcePath, date: Date) -> Int? {
        let request = oauth.request(forURL: NSURL(string: "https://api.fitbit.com/1/user/-/\(resource.rawValue)/date/\(date.toString())/1d.json")!)
        let task = oauth.session.dataTaskWithRequest(request) { data, response, error in
            if error != nil {
                print("[ERROR] An error occured during request: \(error)")
            }
            else {
                print("[SUCCESS] Data retrieved successfully")
                print(ParsingEngine.parseFitbitData(ResourcePath.calories, data: data!))
            }
        }
        task.resume()
        return nil
    }

You're right that the function is returning before your data populates from the server. Why can't you do it from a completion handler? This should work:

static func getFitbitData(resource: ResourcePath, date: Date, completion: (data: Int?) -> Void) {
        var rawData: NSData?
        let request = oauth.request(forURL: NSURL(string: "https://api.fitbit.com/1/user/-/\(resource.rawValue)/date/\(date.toString())/1d.json")!)
        let task = oauth.session.dataTaskWithRequest(request) { data, response, error in
            if error != nil {
                print("[ERROR] An error occured during request: \(error)")
            }
            else {
                print("[SUCCESS] Data retrieved successfully")
                let endData = ParsingEngine.parseFitbitData(ResourcePath.calories, data: data!)
                completion(endData)
            }
        }
        task.resume()
    }

You can call this like so:

FitbitService.getFitbitData(myResource, date: myDate) { data in
   //work with your data here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM