Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I didn't found way to get my body data as json parsing is failing #255

Closed
renetik opened this issue Mar 21, 2020 · 7 comments · Fixed by #256
Closed

I didn't found way to get my body data as json parsing is failing #255

renetik opened this issue Mar 21, 2020 · 7 comments · Fixed by #256

Comments

@renetik
Copy link
Contributor

renetik commented Mar 21, 2020

You totaly blocked api to get to body as data or string.
My server returns body like this (from debugger) :
<__NSSingleObjectArrayI 0x600000aaa320>(
https://img.motofotky.cz/upload/images/forum/2020/12/516269_upload.jpg
)
Parsing returns JSON.none with no way how I can retrieve data while still receiving success.
Although nice library but api is very closed and unable to extend with important pieces not public.
Only way for me to use is fork and edit codebase directly to get to body of response...

Used this method:
public func post(_ path: String, parameters: Any? = nil, parts: [FormDataPart], completion: @escaping (_ result: JSONResult) -> Void) -> String {

@renetik
Copy link
Contributor Author

renetik commented Mar 21, 2020

Data as string looks like this:
"["https:\/\/img.motofotky.cz\/upload\/images\/forum\/2020\/12\/516270_upload.jpg"]"

I am able to parse it perfectly like this:

    func jsonValue() -> Any? {
        if let data = data(using: .utf8) {
            return try? JSONSerialization.jsonObject(with: data, options: [.mutableContainers, .allowFragments])
        }
        return nil
    }

And I get swift array with one string obviously. So I believe parsing in you case is more strict what is in this case not useful at all as we developers sometimes don't have control over server responses or it is so complicated it's best to avoid...

@renetik
Copy link
Contributor Author

renetik commented Mar 21, 2020

So I modified your library but, I just made small change...

public class JSONResponse: Response {
    let json: JSON
    public let body: Any?

    public var dictionaryBody: [String: Any] {
        return json.dictionary
    }

    public var arrayBody: [[String: Any]] {
        return json.array
    }

    public var data: Data {
        switch json {
        case let .array(value, _):
            return value
        case let .dictionary(value, _):
            return value
        case .none:
            return Data()
        }
    }

    init(json: JSON, response: HTTPURLResponse, body: Any? = nil) {
        self.json = json
        self.body = body
        super.init(response: response)
    }
}
        if let finalError = returnedError {
            self = .failure(FailureJSONResponse(json: json, response: response, error: finalError))
        } else {
            self = .success(SuccessJSONResponse(json: json, response: response, body: body))
        }

But I don't believe you want to push this up. Maybe better fix that parser please.

@mkll
Copy link

mkll commented Mar 21, 2020

Data as string looks like this:
"["https://img.motofotky.cz/upload/images/forum/2020/12/516270_upload.jpg"]"

@rene-dohan, Hi, could you post the output of the curl request to the API endpoint here? Just the copy/paste from terminal window. It seems that there is no need to make changes to the library code, you just need to change the parsing method that you use. But this needs to be clarified.

@mkll
Copy link

mkll commented Mar 21, 2020

@rene-dohan, I looked more closely and, as I understand the essence of the problem, you need access to the raw data, but the library does not allow this.

But the library allows. Look at this:

networking.get("/endpoint") { result in
	switch result {
	case .success(let response):
		let jsonData = response.data
	
		do {
			let array = try JSONDecoder().decode([String].self, from: jsonData)
			print(array as Any)
		} catch {
			print(error.localizedDescription)
		}
	case .failure(let response):
		let json = response.dictionaryBody
		print(json)
	}
}

This snippet does just what you need. The result is an array of string values.

@renetik
Copy link
Contributor Author

renetik commented Mar 25, 2020

No becase I see empty data there :) look at your source code please ;)

public var data: Data {
switch json {
case let .array(value, _):
return value
case let .dictionary(value, _):
return value
case .none:
return Data()
}
}

So basically you return empty Data(), I don't know why , what should I do with it ? :) well its probably because you think .none means there was not data in body but as I say youre json parsing failed and in such situation you BLOCKED ACCESS to VALID response body.

I already successfully modified your lib as I told you, to get to body of response but you should be aware of this issue.. It could be quite good library if you make it more flexible, or just make that parsing to return that array :)

@mkll
Copy link

mkll commented Mar 26, 2020

@rene-dohan I am not the author of this library. I just wanted to help. :)

So basically you return empty Data(), I don't know why

In order not to return nil, of course.

@mkll
Copy link

mkll commented Mar 26, 2020

@rene-dohan I conducted a series of experiments and ended up with the fact that we really do not have access to raw data. So you are right.

Could you make a pull request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants