aws-sdk-ios
aws-sdk-ios copied to clipboard
How to initialize AWSMobileClient properly in ObjC without amplify
In general, what are the steps to manually initialize the AWSMobileClient from ObjC? I didn't find documentation.
Which AWS Services are you utilizing?
AWS Cognito AWS S3TransferUtility
Environment:
- SDK Version: 2.8.4
- Dependency Manager: Cocoapods
To be precise:
Should the configuration be stored in awsconfiguration.json or Info.plist? (Which has precedence?)
Do I need to call "initialize"? How (from ObjC)?
What is "Legacy Mode"?
Some context:
I am trying to get the Cognito identity id for the logged in user.
[[AWSMobileClient sharedInstance] getIdentityId]
returns this error:
The operation couldn’t be completed. (AWSMobileClient.AWSMobileClientError error 30)
Note: The user pool signup and login works properly (using the AWSAuthUI)!
Now, I suspected that the AWSMobileClient was not properly initialized, so I added
a call to [[AWSMobileClient sharedInstance] interceptApplication:application didFinishLaunchingWithOptions:launchOptions];
in the AppDelegate.
Then, I got this error:
NSError * domain: @"com.amazonaws.AWSCognitoIdentityErrorDomain" - code: 5
Still, I am able to properly register and login using the AWSAuthUI!
Hello. I had a similar problem with an app that I originally wrote from MobileHub. Use of AuthUI should be replaced with AWSMobileClient.sharedInstance().showSignIn which is available in swift only (as far as a I could find). So, I ended up wrapping all the sign-in and AWSMobileClient to a class in swift code that followed the code in the documentation. AWSMobileClient has been very problematic and has accounted for a significant amount of (lost) development time. But, after a lot of trial and error, I got it to work; possibly a hack.
In ObjC, I wrote a wrapper to handle AWSMobileClient init, sign-in and return the identityId. The main method to check for login looks like this:
// If the user is not signed in then initiate login.
// Return true if the user was already signed in or false if the user was not already signed in.
// If false, return immediately but launch the login view
-(void)checkLogin:(UINavigationController *) navigationController completionHandler:(void (^)(NSString * _Nullable userId, NSError * _Nullable error))completionHandler;
The method is called prior to any access to AWS.
Then, in swift, I wrap all the calls to AWSMobileClient.
You can see from all the comments, it took a lot of trail and error to get it to work. I don't recommend you use the code as it may not be the best. Please wait for a response from AWS. However, if this helps you, please feel free to use it. I'm curious if you can find a better way and for AWS's response.
// AWSMobileClientHelper.swift
//
// Created 12/12/18.
//
import Foundation
import AWSMobileClient
class AWSMobileClientHelper: NSObject {
@objc public static func enableVerboseLogging() {
//AWSDDLog.sharedInstance.logLevel = .verbose;
AWSDDLog.sharedInstance.logLevel = .warning;
//AWSDDLog.sharedInstance.logLevel = .info;
AWSDDLog.sharedInstance.add(AWSDDTTYLogger.sharedInstance);
}
@objc public static func sharedAWSMobileClient() -> AWSMobileClient {
return AWSMobileClient.sharedInstance();
}
@objc public static func signOut() {
AWSMobileClient.sharedInstance().signOut();
}
@objc public static func addUserStateListeners() {
NSLog("AWSMobileClientHelper(swift): addUserStateListeners(): called.")
AWSMobileClient.sharedInstance().addUserStateListener(self) { (userState, info) in
switch (userState) {
case .guest:
NSLog("AWSMobileClientHelper(swift): StateListener: user is in guest mode.")
case .signedOut:
NSLog("AWSMobileClientHelper(swift): StateListener: user signed out")
case .signedIn:
NSLog("AWSMobileClientHelper(swift): StateListener: user is signed in.")
case .signedOutUserPoolsTokenInvalid:
NSLog("AWSMobileClientHelper(swift): StateListener: need to login again.")
case .signedOutFederatedTokensInvalid:
NSLog("AWSMobileClientHelper(swift): StateListener: user logged in via federation, but currently needs new tokens")
default:
NSLog("AWSMobileClientHelper(swift): StateListener: unsupported")
}
}
}
@objc public static func checkLogin(nav: UINavigationController, loginCheckCompletion: @escaping (_ identityId: NSString?, _ error: NSError?) -> Void) {
NSLog("AWSMobileClientHelper(swift): checkLogin: entered.");
AWSMobileClient.sharedInstance().initialize { (userState, error) in
if (error != nil) {
NSLog("AWSMobileClientHelper(swift): checkLogin: error: " + error.debugDescription);
} else {
NSLog("AWSMobileClientHelper(swift): checkLogin: initialize() userState: " + userState!.rawValue);
}
if let userState = userState {
switch(userState){
case .signedIn, .guest:
NSLog("AWSMobileClientHelper(swift): checkLogin: case .signedIn: user is already signed in. okay.");
AWSMobileClient.sharedInstance().getIdentityId().continueWith(block: { (task) -> Any? in
NSLog("AWSMobileClientHelper(swift): checkLogin: case .signedIn: AWSMobileClient.sharedInstance().getIdentityId().continueWith:");
if (task.error == nil){
NSLog("AWSMobileClientHelper(swift): checkLogin: case .signedIn: AWSMobileClient.sharedInstance().getIdentityId().continueWith: no error.");
if let result = task.result {
NSLog("AWSMobileClientHelper(swift): checkLogin: case .signedIn: AWSMobileClient.sharedInstance().getIdentityId() returns identityId: %@", result as String);
}
loginCheckCompletion(task.result, nil);
} else {
NSLog("AWSMobileClientHelper(swift): checkLogin: case .signedIn: AWSMobileClient.sharedInstance().getIdentityId().continueWith: has error." + (task.error?.localizedDescription)!);
if (task.error?._code != 27) {
AWSMobileClient.sharedInstance().signOut();
AWSMobileClient.sharedInstance().clearCredentials()
}
loginCheckCompletion(task.result, task.error as NSError?);
}
return task;
})
default:
if (userState == UserState.signedOutUserPoolsTokenInvalid) {
NSLog("AWSMobileClientHelper(swift): checkLogin: case default: UserState.signedOutUserPoolsTokenInvalid.");
}
if (userState == UserState.signedOutFederatedTokensInvalid) {
NSLog("AWSMobileClientHelper(swift): checkLogin: case default: UserState.signedOutFederatedTokensInvalid.");
}
if (userState == UserState.signedOut) {
// Just show sign-in again
NSLog("AWSMobileClientHelper(swift): checkLogin: case default: UserState.signedOut");
}
NSLog("AWSMobileClientHelper(swift): checkLogin: case default: signing in user via showSignIn...");
AWSMobileClient.sharedInstance().showSignIn(navigationController: nav,signInUIOptions: SignInUIOptions(canCancel: false, logoImage: UIImage( named:"LaunchArt4x4Garage"),backgroundColor: UIColor.modListAccentColor), { (signInUserState, error) in
NSLog("AWSMobileClientHelper(swift): checkLogin: showSignIn() callback: signInUserState = " + signInUserState.debugDescription);
if (signInUserState == nil || error != nil) {
NSLog("AWSMobileClientHelper(swift): checkLogin: showSignIn() callback: has error or no user state:" + error.debugDescription);
}
AWSMobileClient.sharedInstance().getIdentityId().continueWith(block: { (task) -> Any? in
if (task.error == nil){
NSLog("AWSMobileClientHelper(swift): checkLogin: Success. AWSMobileClient.sharedInstance().getIdentityId(): %@", task.result! as String);
loginCheckCompletion(task.result, nil);
} else {
NSLog("AWSMobileClientHelper(swift): checkLogin: AWSMobileClient.sharedInstance().getIdentityId(): returned error " + task.error!.localizedDescription);
if let result = task.result {
NSLog("AWSMobileClientHelper(swift): checkLogin: case default: AWSMobileClient.sharedInstance().getIdentityId() returns identityId: %@", result as String);
}
loginCheckCompletion(task.result, task.error as NSError?);
}
return task;
});
});
}
} else {
if let error = error {
NSLog("AWSMobileClientHelper(swift): checkLogin: userState was nil and there is an error:" + error.localizedDescription);
loginCheckCompletion(nil, error as NSError?);
} else {
NSLog("AWSMobileClientHelper(swift): checkLogin: AWSMobileClient.sharedInstance().initialize returned userState nil!!!");
let errorNilUserState = NSError(domain: "modlist", code: 0, userInfo: [NSLocalizedDescriptionKey : "AWSMobileClient.sharedInstance().initialize returned userState nil and no error"])
loginCheckCompletion(nil, errorNilUserState);
}
}
}
}
}
And, the ObjC wrapper just repeatedly calls it over and over until success and a identityId is not nil.
It may be a hack, but it works. If you find a better solution, please let me know.
[AWSMobileClientHelper checkLoginWithNav:navigationController loginCheckCompletion:^(NSString * _Nullable identityId, NSError * _Nullable error) {
LOG_LOCATION();
self.attempt_count++;
if (error != nil || identityId == nil) {
NSLog(@"checkLogin: checkLoginWithNav callback has error code: %ld error: %@", (long) error.code, error.localizedDescription);
// Disregard Error 27 & 8 and just attempt login again.
if (/* (error.code == 27 || error.code == 8 ) && */ self.attempt_count < 100) {
NSLog(@"checkLogin: Login Failed. Try Again! attempt: %d because: %@", self.attempt_count, error);
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"checkLogin: Login Failed. Try Again! attempt: %d because: %@", self.attempt_count, error);
[[LoginHelper sharedInstance] checkLogin:navigationController completionHandler:^(NSString * _Nullable userId, NSError * _Nullable error) {
self.attempt_count = 0;
checkLoginCompletionHandler(identityId, error);
}];
});
} else {
NSLog(@"checkLogin: Login Failed or too many attempts (%d). Try Again! because: code: %ld error: %@", self.attempt_count, (long)error.code, error.localizedDescription);
self.attempt_count = 0;
self.userId = nil;
checkLoginCompletionHandler(identityId, error);
}
} else {
NSLog(@"checkLogin: checkLoginWithNav returns okay. Sign-in complete. calling checkLoginCompletionHandler.");
self.attempt_count = 0;
self.userId = identityId;
checkLoginCompletionHandler(identityId, nil);
}
}];
});
Good luck!
@thomers Sorry for the inconvenience caused. I will go over your questions one by one.
- Should the configuration be stored in awsconfiguration.json or Info.plist? (Which has precedence?)
awsconfiguration.json
takes precedence over Info.plist
. When you try to create a client object through the SDK, it first looks over the awsconfiguration.json
for the configuration information. If it's not present, it tries to use the Info.plist
.
- Do I need to call "initialize"? How (from ObjC)?
Yes. you need to call the initialize
method of AWSMobileClient
in order to create the Cognito Credentials Provider for getting the identity Id and AWSCredentials.
- What is "Legacy Mode"?
AWSMobileClient
was revamped in 2.7.0
. See https://github.com/aws-amplify/aws-sdk-ios/blob/master/CHANGELOG.md#270 for reference. The flow that AWSMobileClient used to take prior to 2.7.0
is called as legacy mode. AWSMobileClient
has more features to simplify authentication starting 2.7.0
and we recommend you to use that, where we will fix bugs and support new features.
- NSError * domain: @"com.amazonaws.AWSCognitoIdentityErrorDomain" - code: 5
Can you paste the complete error message? Also can you describe your setup? What type of SignIn mechanism (UserPools, Facebook, Google, etc.) are you trying to integrate in your app? Are you federating the SignIn token into Amazon Cognito Federated Identities?
Hey @kvasukib , thanks for the quick response.
"initialize" from AWSMobileClient.swift is not available from ObjC. I tested adding @objc, but that fails:
Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C
How should I call "initialize" from ObjC?
Here's some more information about my setup:
I'm using Cognito User Pools and Cognito Identity Pools (originally coming from a setup from code generated by the old AWS Mobile Hub, then having to migrate to the AWSMobileHubHelper.framework, now having to migrate again...).
No external providers like Facebook or Google for now.
But using Federated Identities to access S3 (and API Gateway, but directly via HTTPS, not using the AWS SDK).
Right now, in my AppDelegate I try to call
[[AWSMobileClient sharedInstance] interceptApplication:application didFinishLaunchingWithOptions:launchOptions];
Interestingly, now this leads to this error messages ("Code 30" instead of "Code 5" before).
[[AWSMobileClient sharedInstance] getIdentityId]
Error fetching identityId: The operation couldn’t be completed. (AWSMobileClient.AWSMobileClientError error 30.)
Error Domain=AWSMobileClient.AWSMobileClientError Code=30 "(null)"
No more info on the error.
@BillBunting , I feel your pain. :-/
To show the signIn-screen, I use this:
[[AWSMobileClient sharedInstance] showSignInScreen:self.navigationController
signInUIConfiguration:signInUIOptions
completionHandler:^(NSString * _Nullable signInProviderKey, NSString * _Nullable signInProviderToken, NSError * _Nullable error) {
The method is found in the internal _AWSMobileClient.h
, which gets imported in AWSMobileClient.h
.
(But maybe this is the even uglier hack - don't know.)
@thomers
"initialize" from AWSMobileClient.swift is not available from ObjC. I tested adding @objc, but that fails:
Yes, this may be the reason I decided to go the "can't beat them, join um route." and put the AWSMobileClient code in swift. Yet, most everything else in my app is ObjC including all access to AWS services (DynamoDB, S3, API Gateway, etc). I went around in circles trying to get it to work in ObjC. I'm very curious and am watching the response closely to see if I could have done things different, and more directly in ObjC. I was also having problems with federated login (still do with Google and token refresh), so I decided I needed to be able to follow the sample code and documentation, only available in swift.
What I concluded at the time, when using AWS 2.8.2 (and now 2.9.x), was that unless the AWSMobileClient was initialized in swift and used exclusively from swift, it created problems.
So, long and short of it, I wrote a AWSMobileClientHelper class in swift. Any time I need to access the AWSMobileClient (form Objc), it goes though swift and this class.
class AWSMobileClientHelper: NSObject {
@objc public static func sharedAWSMobileClient() -> AWSMobileClient {
return AWSMobileClient.sharedInstance();
}
@objc public static func enableVerboseLogging() {
//AWSDDLog.sharedInstance.logLevel = .verbose;
AWSDDLog.sharedInstance.logLevel = .warning;
//AWSDDLog.sharedInstance.logLevel = .info;
AWSDDLog.sharedInstance.add(AWSDDTTYLogger.sharedInstance);
}
@objc public static func signOut() {
AWSMobileClient.sharedInstance().signOut();
}
and so on ... including methods to show the sign in UI posted previously.
Important part... Then, in the AppDelegate.m, I set things up as follows:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(@"application application: %@, openURL: %@, sourceApplication: %@", application.description, url.absoluteURL,
sourceApplication);
// Required for sign-in
return [[AWSMobileClientHelper sharedAWSMobileClient] interceptApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];
//return true;
}
Thanks Bill! I'm curious what AWS / @kvasukib has to say. :)
@thomers @BillBunting Sorry for the inconvenience caused. We are discussing this issue internally and we will post an update here about our findings. Thank you for your patience.
@kvasukib , any update on this issue? Thanks!
@kvasukib , what was the outcome of your internal discussions? How to proceed?
So, I was going through the code in AWSMobileClient.swift and _AWSMobileClient.m and tested a couple of things.
This is my summary:
It seems that AWSMobileClient cannot be correctly initialized from ObjC, at all.
Why?
-
The new, designated initializer
AWSMobileClient.initialize
is not available from ObjC (see above). -
If used in "legacy mode" via
interceptApplication:didFinishLaunchingWithOptions
(found in AWSMobileClient/Internal/_AWSMobileClient.h/.m), the Swift-portion ofAWSMobileClient
fails to get properly initialized. For example,getIdentity()
always fails, probably becauseself.internalCredentialsProvider
gets never set.
This is a huge problem for projects using ObjC (which are still a lot)!
So, I was going through the code in AWSMobileClient.swift and _AWSMobileClient.m and tested a couple of things.
This is my summary:
It seems that AWSMobileClient cannot be correctly initialized from ObjC, at all.
Why?
- The new, designated initializer
AWSMobileClient.initialize
is not available from ObjC (see above).- If used in "legacy mode" via
interceptApplication:didFinishLaunchingWithOptions
(found in AWSMobileClient/Internal/_AWSMobileClient.h/.m), the Swift-portion ofAWSMobileClient
fails to get properly initialized. For example,getIdentity()
always fails, probably becauseself.internalCredentialsProvider
gets never set.This is a huge problem for projects using ObjC (which are still a lot)!
This explains why I had success when I wrapped all calls from Objc to AWSMobileClient in a swift helper class. Calls to DynamoDB, S3, etc. all work fine from Objc once the AWSMobileClient is initialized and sign in is completed in swift via the helper wrapper. (Probably unrelated, but Google Federated sign-in tokens are not automatically refreshed and the user is forced to sign in after every hour of inactivity - Facebook and User Pools work fine)
@BillBunting I guess I'll have to use your approach until AWS replies / fixes the problem.
Did you find out why you had to call getIdentityId()
multiple times to retrieve the identityId? Is this a timing issue?
Maybe my main problem is that I call it only once.
@BillBunting I guess I'll have to use your approach until AWS replies / fixes the problem.
Did you find out why you had to call
getIdentityId()
multiple times to retrieve the identityId? Is this a timing issue?Maybe my main problem is that I call it only once.
A lot of trial and error resulted in calling it multiple times until it was available. What ended up working for me was to repeat until the sign in resulted in returning an identityId.
There is the problem in 2.9.3 too.
Dear Karthikeyan @kvasukib , we'd really appreciate your feedback.
I have to roll back to 2.6.35.
The 2.6.35 version looks like the most stable version for objective-c project.
Or maybe @rohandubal has an answer?
Dear AWS support - @minbi , @kvasukib , @rohandubal - it's been more than 6 weeks that an AWS support member has replied.
What's going on?
I find the lack of support regarding these issues that the changed architecture (new AWSMobileClient, no more AWSMobileHubHelper, AWSContentManager, AWSUserFileManager, etc. etc.) seemed to have caused to me and other paying AWS customers very frustrating.
I want to keep this constructive though: How shall we proceed?
Are you working on a solution for the problems in ObjC-projects?
Should we roll back to 2.6.35?
Thanks!
@thomers Sorry for the delay and inconvenience here. I am going through the thread in detail and will update today on the status here.
@nikhil-dabhade , do you have an update?
@thomers I had a discussion with the team here and am verifying a few details with respect to versions of SDK before I reply here. I will make sure to update you without any further delay.
@nikhil-dabhade thank you, appreciated!
@thomers I went through the details in the thread. I realize the pain points here. The SDKs have had Objective-C functions for all releases until 2.9.0. From version 2.9.0 onwards, we started building all new features for pure Swift SDK only. The initialize method you refer is present for all versions of SDK after 2.9.0 in Swift. The SDK version you are using is 2.8.4 from your environment setup note. This version of the SDK does not have the initialize() function which you also concluded in one of your comments. Using the interceptApplication:didFinishLaunchingWithOptions would be the way to go here. One approach here would be going the same route as @BillBunting where you wrap calls from Obj-C to AWSMobileClient in a swift helper. Given the adoption of Swift and general requests, the plan is to release all future features for pure Swift only. I understand that this may be not the best approach for you in the current scheme of things. However, I am curious about your migration plans to Swift. Can you share what new features after 2.9.0 do you intend to use ? This will help us suggest whether rollback would the way to go.
@nikhil-dabhade thanks for the update!
Note that the initial ticket here is almost 2 months old.
In the meantime, I upgraded to 2.9.x, and wrote a wrapper for AWSMobileClient.
Nevertheless, the problems reappear in different forms, like https://github.com/aws-amplify/aws-sdk-ios/issues/1318 and https://github.com/aws-amplify/aws-sdk-ios/issues/1320
I'm not sure whether the problem is in the ObjC-Swift bridging / wrapper.
The error messages would indicate a problem in my Cognito identity settings, but as I said before, all was working with previous SDK versions, and I didn't change any Cognito settings.
What features do I need?
- Cognito + Federated Logins
- AWS S3 upload/download of files generated by the iOS clients
- Analytics
The underlaying problem I now have with AWS is more serious than a few bugs, though.
It's about trust in the AWS developer infrastructure.
I started 2 years ago with code and configuration generated by AWS MobileHub, including AWSMobileHubHelper as an embedded framework.
Then, AWS suddenly changed the architecture / infrastructure (without any notice), the MobileHub code generator disappeared (so I didn't have a template any longer), and AWSMobileHubHelper was open sourced (found now in the archives at https://github.com/amazon-archives/aws-mobilehub-helper-ios ), along with some other changes.
So I had to refactor. Okay, no problem.
Then in 2018, I found out by accident, that AWSMobileHubHelper is deprecated and will no longer be maintained, and that further development is going to be continued in a new architecture (via AWSMobileClient).
So I had to refactor, again. Hmm... Well, okay.
And then, after trying get AWSMobileClient to work in my project for the last 3 months, I find out (by accident, again) that AWS SDK is going to be "Swift-only"...
Given the adoption of Swift and general requests, the plan is to release all future features for pure Swift only.
...which wouldn't be a huge problem for me, if we are only talking about "future features" - if the core feature set would be working.
It's just not possible to properly initialize the new AWSMobileClient from ObjC (because the interceptApplication: methods are buggy).
The SDKs have had Objective-C functions for all releases until 2.9.0.
Where's the big bold warning in the release notes of 2.9.0 that ObjC-support is (going to be) dropped?
So, regardless whether one has the opinion that ObjC is outdated or not (I don't), the real issue is about stability, longevity, trust.
It's about knowing what we as developers can expect from AWS (a very successful, commercial company, with paid staff - not a few hobbyists opensourcing their project on github), in terms of SDK stability, avoiding breaking changes as much as possible, regression tests, support and fixes for older SDK versions, documentation, response times to tickets...
Don't read this as an angry rant, it really isn't. I'm just trying to raise awareness for the bigger picture.
EDIT, after reading Bill's post below: Thank you guys. I have been working for big software companies myself, and I know it's not your personal fault. Still, it's important for us developers to share our experiences - maybe you can point your managers to this thread...
@thomers , @nikhil-dabhade , @minbi ,
I agree with @thomers . I also started my project about two years ago with AWSMobileHub. I have since had to discontinue using the AWS MobileHub console to manage the project. Shortly after I started the project in MobileHub, MobileHub was "discontinued".
I'm now on my third major refactor of sing-in/sign-up and AWS services access for iOS and a second refactor on Android. I hope this code base will settle down and become more stable, and better documented. Having the code and documentation centralized under amplify in GitHub has helped.
Both iOS and Android versions have been buggy. For example, I reported an issue with AWSMobieClient's ability to refresh tokens with Google Federated sign-in and the issue was open for over a month leaving me unable to release an updated Android version of my app until it was recently resolved. I appreciate @minbi for working to resolve that specific issue. Likewise and prior, I struggled for over a month attempting to get AWSMobieClient to work in my "legacy" iOS project built with MobileHub in Objc. The opportunity cost was very significant for me as I was unable to deliver new features being consumed with just attempting to maintain a login session.
Using AWSMobileClient on both platforms was supposed to make AWS integration simple, so I could focus on application level functional code. But, with so many bugs in both the iOS and Android versions of the AWSMobileClient, I unfortunately may have spent more time on sign-in/sign-up than I would have if I had written it from scratch. I had a prior iOS version of the sign-up screens that was adapted and enhanced from a MobileHub auto generated sample to make user errors more readable and customize the sign-in flow, but unfortunately was forced into AWSMobileClient since the APIs were removed with the switch over to AWSMobileClient. I still have open UI issues for both iOS and Android due to technical non-end-user error validation messages being displayed to users and issues where users are unable to correctly enter international phone numbers due to the requirement to start phone numbers with +1 and vague errors messages resulting in new users simply abandoning their attempt to use the app. There has been some work on these two issues, but not enough to provide a user-friendly experience for a non-technical user base.
At this point, my code is detached from both MobileHub and Amplify management and there is not a path to migrate from MobileHub to Amplify that I am aware of. I need to be able to support an application that is configured outside Amplify, and I need the documentation to support this as well. If there is a migration path to build an amplify configuration from an existing configuration or manually, I'd give it a try. I'd like to achieve the ability to more easily redeploy the server side and get it under configuration management because it is mostly manually configured through the console. (I assume I could use CloudFormation, if I had the time.)
My project was pure Objective C at the start, but due to the removal of support for ObjC with a switch to AWSMobileClient, I also had to add swift support and then a wrapper. Although the wrapper works, the underlying code the manage the login session and tokens is still buggy and by a lot of trial and error, I have it working, mostly. For example, Google users are forced to sign-in every hour since the token does not properly refresh on iOS. I understand Amazon's decision to only support Swift and fortunately, Swift with Objc projects are common and well supported. (But, please don't take away Java on the Android side for Kotlin.)
As I transition from Android development back to iOS soon, I will upgrade from 2.9.1 to 2.9.4. Fingers crossed.
I worry a bit about the next bug, the next API change, etc, but overall am very pleased to be using aws-sdk-android and aws-sdk-ios. I worry that the AWS teams for these projects may not have the resources to respond quickly enough to bugs as the amount of time between reporting bugs and getting attention and fixes can be significant.
I'm committed to using amplify aws-sdk-android and aws-sdk-ios and share my experiences constructively. I appreciate the people making this possible; I know how hard you must be working.
Thank you.
@thomers @BillBunting This is extremely important feedback. I am going over all the details and will revert today. Thank you very much for sharing the detailed insights about your pain points. We want to try and find a constructive way forward for you.
Any news?
Closing this issue