Cannot Invoke 'Decode' with an Argument List of Type '(T, From: Data)'

Swift: Cannot invoke 'decode' with an argument list of type '([Idea], from: Data)'

You have two issues. First is the compiler error from:

let readIdeas = try JSONDecoder().decode(ideas.self, from: jsonData)

That needs to be :

let readIdeas = try JSONDecoder().decode([Idea].self, from: jsonData)

With that fixed you get a runtime error because you wrote the file to the Documents folder but you attempt to read it from the app's resource bundle.

Update your loading code to use the same path used to save the file:

func readIdeasFromJSON(){
do {
let pathDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let filePath = pathDirectory.appendingPathComponent("data.json")

let jsonData = try Data(contentsOf: filePath)
let readIdeas = try JSONDecoder().decode([Idea].self, from: jsonData)
print(readIdeas)
} catch {
print(error)
}
}

Cannot invoke 'decode' with an argument list of type '(T, from: Data)'

The type of the type T is its metatype T.Type, therefore the
function parameter must be declared as type: T.Type.

You may also want to make the completion handle take a parameter of type T instead of Codable:

static func updateDataModels <T : Codable> (url: serverUrl, type: T.Type,
completionHandler:@escaping (_ details: T) -> Void)

When calling the function, use .self to pass the type as an
argument:

updateDataModels(url: ..., type: MainDataFamily.self) { ... }

Cannot invoke 'decode' with an argument list of type '(Codable.Type?

You can use generics like below.

protocol Proto {
}

struct Test: Codable, Proto {
let name: String
let testers: [String]
}

func getData<T>(type: T.Type, configuredRequest:URLRequest?) where T : Decodable {
let data = """
{
"name": "a test",
"testers": ["mike", "bob"],
}
""".data(using: .utf8)!
let test = try? JSONDecoder().decode(type, from: data)
debugPrint(test)
}

getData(type: Test.self, configuredRequest: nil)

Edited.

As commented, you want Type to be a member of the class, which has getData.
In that case you can apply generics to class definition like below.

class DataFetcher<T> where T: Decodable {
func getData(configuredRequest:URLRequest?) {
let data = """
{
"name": "a test",
"testers": ["mike", "bob"],
}
""".data(using: .utf8)!
let test = try? JSONDecoder().decode(T.self, from: data)
debugPrint(test)
}
}

DataFetcher<Test>().getData(configuredRequest: nil)

Cannot invoke 'decode' with an argument list of type '([T.Type], from: Data)

I just realised what I forgot to change in my code and why it wasn't working, so I figured I would share the solution here for anyone that runs into the same problem.

I forgot to make the model input of the type [T] which is why it couldn't decode the given model. So this makes the entire working code look like this

func decodeResult<T: Decodable>(model: [T].Type, result: NSArray) -> (model: [T]?, error: Error?) {
do {
let jsonData = try JSONSerialization.data(withJSONObject: result, options: .prettyPrinted)
let modelObject = try JSONDecoder().decode(model.self, from: jsonData)
return (modelObject, nil)
} catch let error {
return (nil, error)
}
}

Cannot invoke 'decode' with an argument list of type '(GenericDM.Type, from: String?)'

Assuming decode is the normal Decoder decode method. The from parameter expect Data, not an optional String.

let url = Bundle.main.url(forResource: "MockGenericData", withExtension: "json")!
do {
let jsonData = try Data(contentsOf: url)
let genericDM = try newGenericDMJSONDecoder().decode(GenericDM.self, from: jsonData)
} catch {
print(error)
}

Swift compiler error: “Cannot invoke 'map' with an argument list of type '((_) - _)'”

Swift can't infer types from the context every time. If it can't infer types, you have to type them explicitly, in this case the return type:

let patterns = (0...5).map { verseNum -> String in

In this case I believe Swift should be able to infer the type so it might be a bug.

Cannot convert value of type 'Codable' (aka 'Decodable & Encodable') to expected argument type 'T.Type'

What you need is a generic method:

private func parseJson<T: Decodable>(data: Data, type: T.Type) -> T? {
do {
return try JSONDecoder().decode(type.self, from: data)
} catch {
print("JSON decode error:", error)
return nil
}
}

You can also omit the type and explicitly set the type of the resulting object:

private func parseJson<T: Decodable>(data: Data) -> T? {
do {
return try JSONDecoder().decode(T.self, from: data)
} catch {
print("JSON decode error:", error)
return nil
}
}

Playground testing:

struct User: Codable {
let id: Int
let name: String
}
let user: User = .init(id: 2, name: "abc")
let userData = try! JSONEncoder().encode(user)

let decodedUser: User = parseJson(data: userData)!
decodedUser.name // "abc"

Note: I am returning optional types but you should definitely make your methods throw and return a non optional as you can see below where I am extending Data:

extension Data {
func decodedObject<T: Decodable>() throws -> T {
try JSONDecoder().decode(T.self, from: self)
}
}


do {
let decodedUser: User = try userData.decodedObject()
print(decodedUser.name) // "abc"
} catch {
print(error)
}


Related Topics



Leave a reply



Submit