Aws-sdk-ios: Support Swift 4 for API Gateway

Created on 25 Oct 2017  路  5Comments  路  Source: aws-amplify/aws-sdk-ios

I started to migrate our application on Swift 4 but I'm encountering a problem with API Gateway and the model AWSModel generated from the AWS console.

After to have initialized a model and to have set the values, the model send to AWSAPIGatewayClient via the body is empty and the result of AWSTask generate an error.

The operation couldn鈥檛 be completed. (com.amazonaws.AWSAPIGatewayErrorDomain error 2.)

We call often model.debugDescription in the code, and the value appear empty each time. But when I override debugDescription in the model class, the values exist.

**Only requests which use queryParameters via invokeHTTPRequest work well.**

Before migration, everything works on Swift 3.

Thanks by advance for any help 馃槈

Source example

Model class

import AWSCore

public class CLIUserModel: AWSModel {

    var username: String?

    public override static func jsonKeyPathsByPropertyKey() -> [AnyHashable: Any]! {
        var params: [AnyHashable : Any] = [:]
    params["username"] = "username"

    return params
    }
}

ApiClient: AWSAPIGatewayClient

public func usersSelfPut(_ body: CLIUserModel) -> AWSTask<AnyObject> {
    let headerParameters = ["Content-Type": "application/json", "Accept": "application/json"]
    let queryParameters = [String: Any]()
    let pathParameters = [String: Any]()

    return self.invokeHTTPRequest("PUT", urlString: "/users/self", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: body, responseClass: nil)
}

Information

  • What service are you using?
    API Gateway

  • In what version of SDK are you facing the problem?
    2.6.4, 2.6.5

  • Is the issue limited to Simulators / Actual Devices?
    Only tested on physical device (not executable on Simulator due to Metal Framework)

  • Can your problem be resolved if you bump to a higher version of SDK?
    No actually

  • Is this problem related to specific iOS version?
    Only tested on iOS 11

  • How are you consuming the SDK? CocoaPods / Carthage / Prebuilt frameworks?
    Cocoapods

api gateway

Most helpful comment

Why has this issue been closed? I have attempted to use a gateway SDK generated today and I am still running into this issue. Swift 4 has been out for 6 months. It seems absurd to have to manually edit all AWSModel subclasses to target the current language version.

All 5 comments

i have the same issue, please help

TLDR

Here's the solution that worked for me. Add the @objc attribute to each property in your generated-source model class. (Or alternatively, add the @objcMembers attribute directly to the class declaration.) This will allow the Objective-C code to see these properties when generating the APIGateway request.

@objc var username: String?

or

@objcMembers
public class CLIUserModel : AWSModel {

Detail

I had this same issue. I traced the following method calls:

AWSAPIGatewayClient.invokeHTTPRequest
AWSMTLJSONAdapter.JSONDictionaryFromModel
AWSMTLJSONAdapter.JSONDictionary
AWSMTLModel.dictionaryValue
AWSMTLModel.enumeratePropertiesUsingBlock
class_copyPropertyList

Then I found this post on the Swift forums: https://bugs.swift.org/browse/SR-5748

Here's a quote from the forum post:

The problem is that the class_copyPropertyList is an Objective-C function, and so only understands Objective-C concepts. The properties of the [XYZ] class are only Swift properties in your code, and need to be be marked with the @objc attribute for that function to know they exist. This can be done by placing @objc on each property (@objc var id: String = "") or by putting @objcMembers on the class itself (@objcMembers class Factory: NSObject) which is like marking everything in the class with @objc (properties and methods).

So I added @objc to the properties in my generated-source model from APIGateway, and then it worked.

Thank you for your response @hardingmatt, with all details.

In case where you prefer to use @objc on each properties, it's important to add also @objc on the transformer methods.

@objc class func objectsJSONTransformer() -> ValueTransformer { }

Why has this issue been closed? I have attempted to use a gateway SDK generated today and I am still running into this issue. Swift 4 has been out for 6 months. It seems absurd to have to manually edit all AWSModel subclasses to target the current language version.

I still got the same issue with Array.

"Fatal error: NSArray element failed to match the Swift Array Element type".

  • Here's my model :

@objcMembers
public class AWSRegistry: AWSModel{
var a : String?
var b : String?
var c : String?
var d : String?

public override static func jsonKeyPathsByPropertyKey() -> [AnyHashable : Any]!{
    var params:[AnyHashable : Any] = [:]

    params["a"] = "a"
    params["b"] = "b"
    params["c"] = "c"
    params["d"] = "d"

    return params
}

}

  • Calling :
    if let result = task.result {
    let registryList = result as! [AWSRegistry]
    let testValue = registryList[0] // Crashing at here.
    }

Anybody can help me?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mohab2014 picture mohab2014  路  4Comments

pawlowskialex picture pawlowskialex  路  4Comments

cornr picture cornr  路  4Comments

joelk picture joelk  路  5Comments

ChrisInspect picture ChrisInspect  路  4Comments