soto-project / soto

Swift SDK for AWS that works on Linux, macOS and iOS
https://soto.codes
Apache License 2.0
880 stars 83 forks source link

Build error in Xcode when creating simple AWSService instance #458

Closed brocktubre closed 3 years ago

brocktubre commented 3 years ago

Describe the bug I am getting the following error when trying to create a simple S3 AWService instance: Cannot use instance member 'awsClient' within property initializer; property initializers run before 'self' is available

To Reproduce Steps to reproduce the behavior:

  1. Try and create an S3 AWSService instance using the following syntax.
import UIKit
import SotoS3

class S3ViewController: UIViewController {

    let bucket = "my-bucket-abc123"

    var awsClient = AWSClient(
        credentialProvider: .static(accessKeyId: "ACCESS_KEY", secretAccessKey: "SECRET_ACCESS_KEY"),
        httpClientProvider: .createNew
    )
    let s3 = S3(client: awsClient, region: .useast1) <-- ERROR HERE

}

Expected behavior No errors or build failures.

Setup (please complete the following information):

Additional context I am very new to Swift development and might be missing something quite small. Please delete this issue if my setup has nothing to do with using sots.

adam-fowler commented 3 years ago

That's an issue with your Swift code. You can't have one member variable dependent on another if they are initialised like that. At the point you are initialising s3 self doesn't exist so self.awsClient doesn't exist.

Unfortunately you cannot override UIViewController.init easily. Instead you could do the following

class S3ViewController: UIViewController {
    var awsClient: AWSClient!
    var s3: S3!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.awsClient = AWSClient(
            credentialProvider: .static(accessKeyId: "ACCESS_KEY", secretAccessKey: "SECRET_ACCESS_KEY"),
            httpClientProvider: .createNew
        )
        self.s3 = S3(client: awsClient, region: .useast1) <-- ERROR HERE
}

I'm not overly keen on this though. I would prefer that AWSClient is separate from your S3ViewController. It should probably be in some global state. In the future you might change how you acquire your AWS credentials and this might involve network access and you don't want to be asking for credentials every time you display your S3ViewController. Also you might end up using another AWS service and want to use the AWSClient elsewhere.

brocktubre commented 3 years ago

Thanks, @adam-fowler for the quick response! This issue is my lack of knowledge for developing in swift so my applogize! I planned on getting just a bare bone minimal code working before refactoring into what you described above. Let me give the above code a go and see if I can get it working properly. Feel free to close out this issue!