Tomm P
Tomm P

Reputation: 825

How to get Mutable data from an NSURLRequest

I'm trying to retrieve a text file from a URL and then process that text file in the swift Data form. It's like a CSV file but uses "|" for the column delimiter and "}" for the row delimiter.

I'd like to remove the first "line" up to a "}" character (my line delimiter is a "}" so that I can cycle through the file until it's empty.

However NSURLRequest returns an immutable Swift Data object.

I guess I can copy it into a mutable copy but I prefer it if I could persuade NSURLRequest to return a mutable Data object. Is that possible?

My URL request looks like this:

    func load(url: String) {

    debugPrint(#function)
    let url = URL(string: url)!
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            self.handleClientError(error: error)
            return
        }
        guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
                self.handleServerError(error: response)
                return
        }
        debugPrint("data got")

        self.dataGot(data: data!)
        DispatchQueue.main.async {

                self.loadingDelegate!.stockLoadComplete()

        }

    }
    task.resume()


}

currently I'm creating a string from the entire file and doing some string operations to split rows and columns:

        let asString = String(data: data, encoding: String.Encoding.utf8)

    let rows = asString!.components(separatedBy: "}")
    for row in rows {
        self.addPriceLine(line: row)
    }

This approach is failing with a malloc error (after successfully processing a few hundred rows) so I suspect that I'm going down the wrong road somehow.

Is there a "good" or recommended approach? Using just a Data object seems a lot more elegant to me.

Advice appreciated.

Upvotes: 0

Views: 222

Answers (1)

Tomm P
Tomm P

Reputation: 825

OK so I solved the problem.

I was getting a runtime malloc error which made me think there was some problem with the Data buffer or its conversion to a string.

I wandered if it was something failing with memory allocation in the closure so I put the gotData() processing onto the main dispatch queue. Voila - the malloc went away.

Clearly there are limits to what you should do in the closure, rather than the main dispatch queue and I guess I was misusing the approach.

:)

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            self.handleClientError(error: error)
            return
        }
        guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
                self.handleServerError(error: response)
                return
        }
        debugPrint("data got")

        DispatchQueue.main.async {
                self.dataGot(data: data!)

                self.loadingDelegate!.stockLoadComplete()

        }

    }

Upvotes: 0

Related Questions