Coder Social home page Coder Social logo

awslabs / aws-mobile-appsync-sdk-ios Goto Github PK

View Code? Open in Web Editor NEW
261.0 47.0 120.0 73.35 MB

iOS SDK for AWS AppSync.

Home Page: https://awslabs.github.io/aws-mobile-appsync-sdk-ios/

License: Other

Ruby 0.15% Objective-C 0.14% Swift 99.14% Shell 0.54% JavaScript 0.03%
appsync appsync-sdk aws-mobile graphql graphql-client graphql-ios graphql-subscriptions cocoapods ios ios-swift

aws-mobile-appsync-sdk-ios's Introduction

⚠️ AWS AppSync SDK for iOS is in Maintenance Mode

For more information, including how to upgrade to using AWS Amplify API Category, see AWS Amplify > API (GraphQL) > Upgrade guide from AppSync SDK

Recommendation: Use Amplify clients to connect to AppSync

For front-end web and mobile development, we recommend using the Amplify clients which are optimized to connect to the AppSync backend.

  • For DynamoDB data sources, use the DataStore category in the Amplify client. It provides the best developer experience and built-in conflict detection and resolution.
  • For non-DynamoDB data sources in scenarios where you have no offline requirements, use the API (GraphQL) category in the Amplify client.

AWS AppSync SDK for iOS

Release CocoaPods Carthage compatible Build Status Documentation Status Swift Twitter Follow

The AWS AppSync SDK for iOS enables you to access your AWS AppSync backend and perform operations like Queries, Mutations, and Subscriptions. The SDK also includes support for offline operations. This SDK is based off of the Apollo project found here. Please log questions for this client SDK in this repo and questions for the AppSync service in the official AWS AppSync forum.

Setup

Note: AWS AppSync uses Swift 5.1. Use Xcode 11.0 or greater to build.

Installing the SDK

Via Swift Package Manager

  1. Swift Package Manager is distributed with Xcode. To start adding the AWS SDK to your iOS project, open your project in Xcode and select File > Swift Packages > Add Package Dependency.

  2. Enter the URL for the AWS AppSync SDK for iOS GitHub repo (https://github.com/awslabs/aws-mobile-appsync-sdk-ios) into the search bar and click Next.

  3. You'll see the repository rules for which version of the SDK you want Swift Package Manager to install. Choose the first rule, Version, and select Up to Next Major as it will use the latest compatible version of the dependency that can be detected from the main branch, then click Next.

  4. Choose the AWSAppSync package product and click Finish.

  5. In your source file, import the SDK using import AWSAppSync.

Via CocoaPods

  1. Add the following line to your Podfile:

    pod 'AWSAppSync', '~> 3.7.0'

    Example:

    # Uncomment the next line to define a global platform for your project
    # platform :ios, '9.0'
    
    target 'EventsApp' do
      # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
      use_frameworks!
    
      # Pods for EventsApp
      pod 'AWSAppSync', '~> 3.7.0'
    end
  2. Run pod install to install the AppSync SDK, then open the .xcworkspace file (not the .xcodeproj file) in Xcode.

  3. Now Build your project to start using the SDK. Whenever a new version of the SDK is released you can update by running pod update and rebuilding your project to use the new features.

  4. In your source file, import the SDK using import AWSAppSync.

Via Carthage

XCFrameworks (recommended)

Carthage supports XCFrameworks in Xcode 12 or above. Follow the steps below to consume the AWS SDK for iOS using XCFrameworks:

  1. Install Carthage 0.37.0 or greater.

  2. Add the following to your Cartfile:

    github "awslabs/aws-mobile-appsync-sdk-ios"
    
  3. Then run the following command:

     $ carthage update --use-xcframeworks
    
  4. On your application targets’ General settings tab, in the Embedded Binaries section, drag and drop each xcframework you want to use from the Carthage/Build folder on disk.

Note: If you are using XCFrameworks (i.e., either Carthage or Dynamic Frameworks), the module AWSMobileClient is named as AWSMobileClientXCF to work around a Swift issue. To use AWSMobileClient, import it as:

    import AWSMobileClientXCF

and use it your app code without the XCF suffix.

    AWSMobileClient.default.initialize()
Frameworks with "fat libraries" (not recommended)

To build platform-specific framework bundles with multiple architectures in the binary, (Xcode 11 and below)

  1. Add the following to your Cartfile:

    github "awslabs/aws-mobile-appsync-sdk-ios"
    
  2. Once complete, run carthage update and open the *.xcworkspace with Xcode and chose your Target. In the General tab, find Embedded Binaries, then choose the + button.

  3. Choose the Add Other button, navigate to the AWS<#ServiceName#>.framework files under Carthage > Build > iOS and select AWSAppSync.framework and its required dependencies:

    • AWSAppSync.framework
    • AWSCore.framework
    • Reachability.framework
    • SQLite.framework
    • AppSyncRealTimeClient.framework
    • Starscream.framework

    Do not select the Destination: Copy items if needed check box when prompted.

  4. Under the Build Phases tab in your Target, choose the + button on the top left and then select New Run Script Phase. Setup the build phase as follows. Make sure this phase is below the Embed Frameworks phase.

    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCore.framework/strip-frameworks.sh"

    Options:

    • Shell: /bin/sh
    • Show environment variables in build log: Checked
    • Run script only when installing: Not checked
    • Input Files: Empty
    • Output Files: Empty
  5. Now Build your project to start using the SDK. Whenever a new version of the SDK is released you can update by running carthage update and rebuilding your project to use the new features.

    Note: Currently, the AWSAppSync SDK for iOS builds the Carthage binaries using Xcode 12.0. To consume the pre-built binaries your Xcode version needs to be the same. Otherwise you will have to build the frameworks on your machine by passing --no-use-binaries flag to carthage update command.

  6. In your source file, import the SDK using import AWSAppSync.

Codegen

To use the AppSync SDK, you will need to use amplify codegen from the AWS Amplify CLI. This command will generate Swift-language files corresponding to your schema. You can interact with these classes instead of operating on GraphQL query documents, directly. You can find the instructions to use the codegen here.

Sample

You can find a sample app which uses the AppSync SDK here: https://github.com/aws-samples/aws-mobile-appsync-events-starter-ios

Documentation

You can find a step by step walk through of setting up codegen backend and accessing it via the iOS client here: https://docs.amplify.aws/sdk/api/graphql/q/platform/ios

Contributing

Contributing guidelines are noted here.

Testing Contributions

If you are contributing to the SDK, it is recommended to add some unit and/or integration tests and evaluate against existing tests.

Invoking tests

The AWSAppSync target is configured to run both Unit and Integration tests in its Test configuration. After completing integration test setup following the instructions below, you can run both suites by invoking "Product > Test" (⌘-U) in Xcode.

To run only one suite of tests (Unit or Integration), select the appropriate target from the Scheme selector and invoke "Product > Test" (⌘-U). While Unit tests run much faster than Integration tests, we recommend running both before submitting a PR.

Setting up unit tests

Unit Tests do not require any specific setup and can be run directly from your Xcode IDE.

  • NOTE: Currently, any test that requires network activity is placed in Integration tests, even if the test hits localhost and not a valid service.

Setting up integration tests

To run integration tests, you will need the following:

  • Two AppSync API instances with an Posts schema.
    • The first AppSync instance should be configured to use a Cognito Identity Pool with unauthenticated identities supported.
      • The Cognito Identity Pool's unauth role should have the AppSync Invoke Full Access permission.
    • The second instance should be configured to use API Key authentication.

You can get the backend setup by following the steps below:

  1. Create a stack with an AppSync API using API Key authentication
    1. Go to the AWS CloudFormation console.
    2. Click on Create stack and then select Upload a template file. Click Choose File, and navigate to the Cloud Formation Template in this project: AWSAppSyncIntegrationTests/ConsoleResources/appsync-integrationtests-cloudformation.yaml
    3. Click Next
    4. Type a "Stack name" and a "ResourceNamePrefix"
      • We recommend using a "ResourceNamePrefix" that makes it easy to tell that the stack is used for AppSync tests, such as AppSyncTest<YYYYMMDDHHMM>.
      • Because you will create two stacks for these tests, one using API Key authentication and one using IAM (Cognito Identity) authentication, we recommend selecting a stack name that makes it easy to differentiate between the two, such as AppSyncTest<YYYYMMDDHHMM>-APIKey and AppSyncTest<YYYYMMDDHHMM>-IAM.
    5. Select the ApiKey Auth Type
    6. Once the stack is complete, click on the Output tab.
    7. Copy the appropriate values to the test configuration file AppSyncIntegrationTests/appsync_test_credentials.json:
      • AppSyncApiKey
      • AppSyncEndpointAPIKey
      • AppSyncEndpointAPIKeyRegion
  2. Create another CloudFormation Stack following steps 1-6 above, but select the "IAM" Auth Type in step 5.
    1. Copy the appropriate values to the test configuration file AppSyncIntegrationTests/appsync_test_credentials.json:
      • AppSyncEndpoint
      • AppSyncRegion
      • CognitoIdentityPoolId
      • CognitoIdentityPoolRegion
      • BucketName
      • BucketRegion
      • AppSyncMultiAuthAPIKey
  3. Create another CloudFormation Stack following step 1-6 above with API Key as the Auth type (we'll change that later)
    1. Create a Lambda function using the template provided in this project at AWSAppSyncIntegrationTests/ConsoleResources/appsync-lambda-authorize r.js

    2. Once the stack is complete click on the Outputs tab

    3. Copy the appropriate values to the test configuration file AppSyncIntegrationTests/appsync_test_credentials.json:

      • AppSyncEndpointAPIKeyLambda
      • AppSyncEndpointAPIKeyLambdaRegion
    4. Go to the AWS AppSync console, select the newly created AppSync instance

    5. In the Settings section, change the default authentication type to AWS Lambda and select the Lambda function created at the previous step

Note: You must either provide all values in the AppSyncIntegrationTests/appsync_test_credentials.json or in code. There is no mechanism to handle partial overrides of one source with the other. All values must be specified before running the integration tests.

Option 1: Use a test configuration file

Add a file appsync_test_credentials.json (see sample below) in the AWSAppSyncIntegrationTests folder and replace the values for AppSyncEndpoint, CognitoIdentityPoolId, AppSyncEndpointAPIKey, AppSyncAPIKey and regions if required:

{
  "AppSyncEndpoint": "https://iambasedendpoint.appsync-api.us-east-1.amazonaws.com/graphql",
  "AppSyncRegion": "us-east-1",
  "CognitoIdentityPoolId": "us-east-1:abcd1234-1234-12324-b4b7-aaa0c0831234",
  "CognitoIdentityPoolRegion": "us-east-1",
  "AppSyncEndpointAPIKey": "https://apikeybasedendpoint.appsync-api.us-east-1.amazonaws.com/graphql",
  "AppSyncEndpointAPIKeyRegion": "us-east-1",
  "AppSyncAPIKey": "da2-sad3lkh23422",
  "BucketName": "bucketName",
  "BucketRegion": "us-east-1",
  "AppSyncMultiAuthAPIKey": "da2-sd34s5ffxz"
}

Note: The AppSyncEndpointAPIKey endpoint uses API_KEY based auth, while AppSyncEndpoint uses the AWS_IAM based auth.

Option 2: Edit defaults in source code

Edit the file AWSAppSyncTestCommon/AppSyncClientTestConfigurationDefaults with appropriate values.

Now you should be able to run the integration tests by invoking "Product > Test" (⌘-U) in Xcode.

License

This library is licensed under the Amazon Software License.

aws-mobile-appsync-sdk-ios's People

Contributors

5d avatar ameter avatar atierian avatar brennanmke avatar dependabot[bot] avatar desokroshan avatar diegocstn avatar frankmuellr avatar gleue avatar harsh62 avatar jamesonwilliams avatar jellybeansoup avatar jpeddicord avatar lachlanmcculloch avatar larryonoff avatar lawmicha avatar mariobajr avatar minbi avatar palpatim avatar phantumcode avatar prajaktatathavadkar avatar rohandubal avatar royjit avatar ruiguoamz avatar ruisebas avatar scb01 avatar stefanceriu avatar thisisabhash avatar undefobj avatar wooj2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-mobile-appsync-sdk-ios's Issues

Subscription connection handler

Do you know some way to handle subscription success connection?
I was made some changes in AWSAppSyncSubscriptionWatcher to handle this, but maybe you know better way

    private func startSubscription()  {
        let semaphore = DispatchSemaphore(value: 0)
        
        self.performSubscriptionRequest(completionHandler: { [weak self] (success, error) in
            if let error = error {
                self?.resultHandler(nil, nil, error)
            }
            semaphore.signal()
+            if let handle = self?.completeHandler {
+                self?.handlerQueue.async {
+                    handle()
+                }
+            }
        })
        
        semaphore.wait()
    }

Incompatible with Swift 4.1

When installing with Carthage I get this error.

Incompatible Swift version - framework was built with 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38) and the local version is 4.1 (swiftlang-902.0.48 clang-902.0.37.1).

Are there any plans to update the repo to Swift 4.1 soon?

Deadlock on mutation

Describe the bug
I have a case where I have to fire mutations every few seconds. In a case when there are over 2 mutations and you go to background and then back to foreground the app is being deadlocked permanently (main thread is locked). The only way to fix the deadlock is to completely remove the app from the device and then install again.

To Reproduce
Steps to reproduce the behavior:

  1. Every 2 seconds fire 2 similar mutations (destroy client on entering background and recreate on getting back to foreground)
  2. Transfer app to background
  3. Bring the app back to the foreground
  4. You should see that the interface became unresponsive and upon pausing with the debugger there should be a stack trace.

Expected behavior
Shouldn't deadlock

Screenshots
image

Environment(please complete the following information):

  • AppSync SDK Version: [2.6.21]
  • Dependency Manager: [Carthage]
  • Swift Version : [4.2]

Device Information (please complete the following information):

  • Device: [iPhone7]
  • iOS Version: [iOS 12.0]

Automatically upload multiple S3 files support

Hi there,

I would like to get a chance to support automatically uploading multiple S3 files. Currently, as my schema, I have a field: files: [S3ObjectInput], but seems the SDK doesn't support a list of objects like that. I was able to get it worked with one object: file: S3ObjectInput.

Any ideas will be very much appreciated.
Thanks.

Update podspec

Hi,

The podspec needs an update for SQLite.swift.

SQLite.swift 0.11.4 -> SQLite.swift 0.11.5

Handle the AWSAppSyncClient timeout

I am trying my hands on with AppSync iOS and want to get a failure callback for a fetch query when the internet is not available.

When the internet is available, the following code outputs both "sending" and "receiving". But when the internet is not available, I do not get any callback from AppSync client. The code only outputs "sending".

`print("sending")
self.appSyncClient?.fetch(query: getCategoriesQuery, cachePolicy: .fetchIgnoringCacheData) { (result, error) in

    print("receiving")
    if let error = error as? AWSAppSyncClientError {
        print("Error getting Categories from AppSync API: \(error.localizedDescription )")
    }
    else {
        print("Result - ", result?.data?.getCategories?.items!)
    }
}`

After the network timeout, the xCode console outputs

"HTTP load failed (error code: -1001 [1:60])"

"finished with error - code: -1001"

How can I handle the network failure here? Any help is appreciated.

Optimistic update fails if cache is empty

State your question
Optimistic update always fail to "missingValue", if model wasn't previously cached from a fetch query. And said fetch operation needs to actually populate the cache with items, for further optimistic updates, otherwise (i.e. cache is empty) the optimistic update won't update/initialize the cache(?)

Don't know how could I initialize an empty cache just in case the first mutation fails to reach backend, and needs to be written on cache/localDB

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.22
  • Dependency Manager: CocoaPods
  • Swift Version : 4.2

Device Information (please complete the following information):

  • Device: Simulator
  • iOS Version: iOS 12

Unit tests

I'm looking to contribute with a couple of PRs, but just want to clarify what the current state of testing is with regards to PRs and if there's anything going on behind the scenes to improve this? I've seen the AWSAppSyncClientTests group, but it's empty at present.
Thanks.

Errors not returned for Queries

Describe the bug
Working with lambda resolvers (specifically with golang), returning errors are correctly returned to the client when working with mutations, but not with queries.

Handler Signature

func Handler(ctx context.Context, req map[string]interface{}) (SomeObjType, error) 

appSync?.perform(mutation: someMutation) {result, err in

The above will return the error object in result.errors of a mutation, however:

appSync?.fetch(query: someQuery) {result, err in

Will return the errors neither in result or err.

Resolver mapping in both cases:
$util.toJson($context.result)

Expected behavior
Errors returned by lambda should go somewhere when fetching.

Environment(please complete the following information):

  • AppSync SDK Version: '~>2.6.15'
  • Dependency Manager: Cocoapods
  • Swift Version : 4

Conflicting memory management behaviour between AppSyncMQTTClient and MQTTSubscritionWatcher

Hi,
while working on #28 crash fix pointed in #39, I noticed that AppSyncMQTTClient strongly holds all MQTTSubscritionWatcher instances in topicSubscribersDictionary. The only way to remove those instances is to call stopSubscription(subscription:) passing the watcher in the argument. This could be a desired behaviour, but it conflicts with AWSAppSyncSubscriptionWatcher, which is the only implementation of MQTTSubscritionWatcher protocol, calling stopSubscription(subscription:) on deinit. In this approach It's impossible to have the execution of deinit without first releasing the reference in AppSyncMQTTClient by calling stopSubscription(subscription:) explicitly, and then having it called again by deinit.

how can I send a push notification (apns) when using appsync

what is the best workflow to use in order to send push notifications to an iOS device when using appsync.

I have a chat app and want users to receive push notifications from apns when they are not using the app and a message is sent to them.

I have all the certificates and have successfully sent push notifications from the sns console. I don't know however how to integrate that with appsync.

My thoughts are to use a lambda function to send the notification directly when an appsync message is sent but could not find any examples on how to do that.

how to assign DAX as Data Source for appSync API

@muellerfr Hi, I am using AppSync to get realTime data for my app. Since it involves lot of transactions, I want to have DAX for my DynamoDB. But I am not able to assign the endpoint as dataSource for the API. Here are the images. How can I solve this
screenshot 2018-10-17 at 3 47 13 pm

screenshot 2018-10-17 at 3 46 31 pm

App come back to foreground after 10 minutes sleep

When app sleep 10 minutes and come back to foreground I receive log like below

2018-09-21 10:44:31.248292+0900 [AppDelegate.swift:118] applicationWillResignActive - 【applicationWillResignActive】
2018-09-21 10:44:31.856556+0900 [AppDelegate.swift:133] applicationDidEnterBackground - 【applicationDidEnterBackground】
2018-09-21 11:03:57.213634+0900 [AppDelegate.swift:123] applicationWillEnterForeground - 【applicationWillEnterForeground】
2018-09-21 11:03:57.231934+0900 [] nw_socket_get_input_frames recvmsg(fd 5, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232051+0900 [] nw_socket_get_input_frames recvmsg(fd 27, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232086+0900 [] nw_socket_get_input_frames recvmsg(fd 29, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232137+0900 [] nw_socket_get_input_frames recvmsg(fd 30, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232166+0900 [] nw_socket_get_input_frames recvmsg(fd 31, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232197+0900 [] nw_socket_get_input_frames recvmsg(fd 32, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232224+0900 [] nw_socket_get_input_frames recvmsg(fd 40, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232251+0900 [] nw_socket_get_input_frames recvmsg(fd 42, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232278+0900 [] nw_socket_get_input_frames recvmsg(fd 44, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232311+0900 [] nw_socket_get_input_frames recvmsg(fd 45, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232378+0900 [] nw_socket_get_input_frames recvmsg(fd 47, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232454+0900 [] nw_socket_get_input_frames recvmsg(fd 52, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232491+0900 [] nw_socket_get_input_frames recvmsg(fd 53, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232525+0900 [] nw_socket_get_input_frames recvmsg(fd 54, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232576+0900 [] nw_socket_get_input_frames recvmsg(fd 55, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232619+0900 [] nw_socket_get_input_frames recvmsg(fd 56, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232677+0900 [] nw_socket_get_input_frames recvmsg(fd 57, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232708+0900 [] nw_socket_get_input_frames recvmsg(fd 58, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.232735+0900 [] nw_socket_get_input_frames recvmsg(fd 59, 1024 bytes) [57: Socket is not connected]
2018-09-21 11:03:57.234904+0900 TIC Read Status [13:0x0]: 1:57
2018-09-21 11:03:57.234926+0900 TIC Read Status [13:0x0]: 1:57
2018-09-21 11:03:57.235710+0900 [PinRoomsController.swift:538] prepareOnDeleteRoomObserver() - ...discomplete
2018-09-21 11:03:57.236290+0900 [GroupRoomsController.swift:1052] prepareOnDeleteManualRoomObserver() - Error occurred: AWSAppSyncSubscriptionError(additionalInfo: Optional("Subscription Terminated."), errorDetails: Optional(["status": "5", "recoverySuggestion": "Restart subscription request.", "failureReason": "Disconnected from service."]))

It's look like socket is disconnected. Do you know good solution for this situation?

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

I'm getting a fatal error trying to run my new mutation:

stack trace:

#6	0x0000000105995fd8 in AWSMutationCache.saveMutationRecord(record:) at /Users/michael/fun/sketchaphone/Pods/AWSAppSync/AWSAppSyncClient/AWSSQLLiteNormalizedCache.swift:89
#7	0x000000010598f31c in MutationExecutor.queueMutation(mutation:) at /Users/michael/fun/sketchaphone/Pods/AWSAppSync/AWSAppSyncClient/AWSOfflineMutationStore.swift:187
#8	0x000000010596f920 in PerformMutationOperation.init(offlineMutationRecord:client:appSyncClient:offlineExecutor:mutation:handlerQueue:mutationConflictHandler:resultHandler:) at /Users/michael/fun/sketchaphone/Pods/AWSAppSync/AWSAppSyncClient/AWSAppSyncClient.swift:541
#9	0x000000010596d988 in PerformMutationOperation.__allocating_init(offlineMutationRecord:client:appSyncClient:offlineExecutor:mutation:handlerQueue:mutationConflictHandler:resultHandler:) ()
#10	0x000000010596d3d0 in AWSAppSyncClient.perform<A>(mutation:queue:optimisticUpdate:conflictResolutionBlock:resultHandler:) at /Users/michael/fun/sketchaphone/Pods/AWSAppSync/AWSAppSyncClient/AWSAppSyncClient.swift:484
#11	0x0000000104c7469c in GamesManager.joinGame(delegate:) at /Users/michael/fun/sketchaphone/sketchaphone/API/GamesManager.swift:233

I'm sure i could be going something wrong, but i'm unclear what it is - and it probably shouldn't crash my app.

My lambda job (which backs the mutation) isn't logging anything so i'm assuming isn't getting executed. My other mutation is working.

my app code is here:
https://github.com/michaeleconomy/sketchaphone

Large strings get truncated - perhaps in sqlite normalized cache

Describe the bug
We were sending some base64 encoded data as a field in a resolver and found this issue after noticing that the data was truncated/corrupt.

To Reproduce
Steps to reproduce the behavior:

  1. In a resolver request mapping (ours is just a none data source) send a long string like this:

    #set($template = {
    "field1": "foo",
    "field2": "bar",
    "auditsExtensions": "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222244444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444455555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555566666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
    })
    {
    "version": "2017-02-28",
    "payload": $util.toJson($template)

}
Response mapping:
$util.toJson($context.result)

  1. This string is roughly 2400 characters long. We have base64 encoded data but we can simplify this example.
  2. Our iOS appsync client returns this data truncated from our watch/fetch query.
  3. We confirmed that the data is correctly sent over HTTP from appsync in the graphql response.
  4. The truncated data is exactly 1024 characters long

Expected behavior
Either a documented size limit or no truncation.

Screenshots
If applicable, add screenshots to help explain your problem.

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.21
  • Dependency Manager: Cocoapods
  • Swift Version : 4.0

Device Information (please complete the following information):

  • Device: iPad current generation
  • iOS Version: iOS 12

Additional context
Any short term hints/workarounds would be greatly appreciated as we're working against a deadline. Happy to work on a patch if needed.

Thanks...

SQLite crashed on runtime

Describe the bug
When run the app got crashed about SQLite

To Reproduce
Steps to reproduce the behavior:

  1. Run App

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.
screen shot 2018-10-13 at 12 54 00 am

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.22
  • Dependency Manager: Carthage
  • Swift Version : 4.2

Device Information (please complete the following information):

  • Device: iPhone SE Simulator
  • iOS Version: iOS 11.4
  • Specific to simulators:

Additional context
Add any other context about the problem here.

Optimistic update: Error at path "<query_with_pagination>.nextToken": missingValue

The query with argument within optimistic update closure will fail with "missingValue" message.
The query is paginated.

Version of AppSync:
2.6.18

Message I'm getting:
Error at path "listJobsByCustomer.nextToken": missingValue

Mutation:
updateJob(input: UpdateJobInput!): Job

Query called in optimistic update closure:
listJobsByCustomer(customerId: String, first: Int, after: String): JobConnection

JobConnection:

type JobConnection {
	items: [Job]
	nextToken: String
}

Code:

let mutation = UpdateJobMutation(input: input)

appSyncClient?.perform(mutation: mutation, optimisticUpdate: { (transaction) in
	do {
		// Update our normalized local store immediately for a responsive UI
		let query = ListJobsByCustomerQuery(customerId: "customerId", limit: 1)
		try transaction?.update(query: query) {
			(data: inout ListJobsByCustomerQuery.Data) in

			for i in 0..<(data.listJobsByCustomer?.items)!.count {
				if data.listJobsByCustomer?.items?[i]?.id == input.id {
					data.listJobsByCustomer?.items?[i]?.status = input.status!
				}
			}
		}
	} catch let exception {
		print("UpdateJobMutation Error updating the cache with optimistic response: \(exception.localizedDescription)")
	}
}) { (result, error) in
	if let error = error as? AWSAppSyncClientError {
		print("Error occurred: \(error.localizedDescription )")
		return
	}
	
	if let res = result {
		print("UpdateJobInfo result: \(res)")
	}
	
	self.handleNetworkStateOnResult(online: true)
}

AWSAppSyncSubscriptionWatcher .cancel() is not work

Describe the bug
Even if you call cancel () on AWSAppSyncSubscriptionWatcher, Memory is not released.

To Reproduce
I am creating a chat application
I was using the same UIViewController in several rooms
When entering the room Initialize with

messageWatcher?.cancel()
messageWatcher = nil

And instantiating subscription with

messageWatcher = try appSyncClient.subscribe

As I enter the room many times, the number of instances continues to increase,
Memory usage will continue to increase

Looking at Xcode's Debug Memory Graph, it is as follows

____________________________2018-10-12_19 13 52

Please tell me if there is a solution.

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.21
  • Dependency Manager: None
  • Swift Version : 4.1

Device Information (please complete the following information):

  • Device: iPhoneX
  • iOS Version: iOS 11.4.1

Additional context

  • Using Xcode10

Crash on unsubscribing a Watcher

When you have several watchers for the one topic the app will crash trying to cancel the subscription

The problem lies in the line of the code that modifies array while iterating on it regarding the upper loop. Here is the case:

  • we have 3 watchers for the same topic.
  • for i == 0 we remove one subscription. Right now array has 2 elements
  • However the Loop is from 0 to 3 and it crashes on the i == 2
        for i in 0..<self.topicSubscribersDictionary[topic]!.count {
                        if watcherToRemove.getIdentifier() == subscription.getIdentifier() {
                            // remove that watcher for no further notification
                            self.topicSubscribersDictionary[topic]!.remove(at: i)
                        }
        }

In addition I have a concern: as long as there is no enforcing of a single thread and self.topicSubscribersDictionary can be modified (until it's really ensured not) from the background thread thus making the whole code of stopSubscription to crash due to force unwrapping in many places.

P.s. I made a PR just to provide a solution example

how can I set the appsync config using swift?

I have been trying to use the appsync service using user pools for authentication but cannot setup the configuration correctly.

I want to use:

let appSyncConfig = try AWSAppSyncClientConfiguration(url: AppSyncEndpointURL, serviceRegion: AppSyncRegion, userPoolsAuthProvider: CognitoUserPoolsAuthProvider(pool: pool))

But I get: use of unresolved identifier 'CognitoUserPoolsAuthProvider'

and if I use AWSCognitoUserPoolsAuthProvider(pool: pool) the error is:

'AWSCognitoUserPoolsAuthProvider' cannot be constructed because it has no accessible initializers

How can I set the configuration correctly to use user pools with appsync?

Sending 2 mutations sequentially, callback doesn't get called on one of them

Describe the bug
When you send two mutations, one right after the other, a callback will get called for one of them, but not for the other one.

To Reproduce
Steps to reproduce the behavior:

  1. Send 2 mutations one right after the other
  2. in the resultHandler callback of the perform(mutation:queue:optimisticUpdate:conflictResolutionBlock:resultHandler:) method, print a log statement

Expected behavior
The callback should be called twice, once for each mutation that was sent.

Screenshots
If applicable, add screenshots to help explain your problem.

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.21
  • Dependency Manager: Cocoapods
  • Swift Version : 4.2 (xcode 10)

Device Information (please complete the following information):

  • Device: iPad Pro (9.7-inch)
  • iOS Version: (11.3)

Additional context
If you wait for the first mutation to complete, then call the second everything works as expected. This was working fine in a previous version of app sync, I have not yet identified which version it broke in.

Mock Response from server to allow for Tests against mock data

Wondering if there is a sanctioned way to mock out data responses from the server so we can implement UI Tests against that mock data.

I've tried a couple different approaches so far. The first is setting up a custom URLSessionConfiguration with a Mock URL Cache that just returns mock data whenever the URL cache is checked by the URLSession. I haven't quite gotten this to work yet, and it seems a bit hacky, but is a possible solution.

The other thing I'm thinking about trying is modifying the AWSAppSyncClientConfiguration to expose the ApolloCache so our application can inject a custom ApolloCache implementation that returns mock data. This seems to be the preferred way of mocking data in Apollo (apollographql/apollo-ios#188)

The second approach would require a modification to the AppSync framework. I'd be happy to submit a PR for this, but wanted to make sure there wasn't some other approach I haven't considered yet.

SQL Lite locked after a mutation

Thread 6: Fatal error: 'try!' expression unexpectedly raised an error: database is locked (code: 5) in SQLLite after a mutation

The exception occurs in the merge function when we try to perform many mutation in less than a second

public final class AWSSQLLiteNormalizedCache: NormalizedCache {

public init(fileURL: URL) throws {
    db = try Connection(.uri(fileURL.absoluteString), readonly: false)
    try createTableIfNeeded()
}

public func merge(records: RecordSet) -> Promise<Set<CacheKey>> {
    return Promise { try mergeRecords(records: records) }
}

public func loadRecords(forKeys keys: [CacheKey]) -> Promise<[Record?]> {
    return Promise {
        let records = try selectRecords(forKeys: keys)
        let recordsOrNil: [Record?] = keys.map { key in
            if let recordIndex = records.index(where: { $0.key == key }) {
                return records[recordIndex]
            }
            return nil
        }
        return recordsOrNil
    }
}

Carthage build fails

When building with Carthage, the AWSAppSync build script fails. It looks to be in relation to some Cocoapods dependencies.

I have removed the /Users/joelbell/Library/Caches/org.carthage.CarthageKit folder and the Carthage/ folder from my project and I still see this issue.

This is my Carthage update command:
carthage update --platform ios --color auto --no-use-binaries

Below is a portion of the error log that is relevant.

PhaseScriptExecution [CP]\ Check\ Pods\ Manifest.lock /Users/joelbell/Library/Caches/org.carthage.CarthageKit/DerivedData/9.3_9E145/aws-mobile-appsync-sdk-ios/2.6.15/Build/Intermediates.noindex/ArchiveIntermediates/AWSAppSync/IntermediateBuildFilesPath/AWSAppSyncClient.build/Release-iphoneos/AWSAppSync.build/Script-4E996121F39BA74DB553A2CB.sh
    cd /Users/joelbell/dev/SIC/abx-sic-operator/Carthage/Checkouts/aws-mobile-appsync-sdk-ios
    /bin/sh -c /Users/joelbell/Library/Caches/org.carthage.CarthageKit/DerivedData/9.3_9E145/aws-mobile-appsync-sdk-ios/2.6.15/Build/Intermediates.noindex/ArchiveIntermediates/AWSAppSync/IntermediateBuildFilesPath/AWSAppSyncClient.build/Release-iphoneos/AWSAppSync.build/Script-4E996121F39BA74DB553A2CB.sh
diff: /Podfile.lock: No such file or directory
diff: /Manifest.lock: No such file or directory
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

** ARCHIVE FAILED **


The following build commands failed:
	PhaseScriptExecution [CP]\ Check\ Pods\ Manifest.lock /Users/joelbell/Library/Caches/org.carthage.CarthageKit/DerivedData/9.3_9E145/aws-mobile-appsync-sdk-ios/2.6.15/Build/Intermediates.noindex/ArchiveIntermediates/AWSAppSync/IntermediateBuildFilesPath/AWSAppSyncClient.build/Release-iphoneos/AWSAppSync.build/Script-4E996121F39BA74DB553A2CB.sh
(1 failure)

returnCacheDataElseFetch returning nil instead of fetching

Describe the bug
When using the CachePolicy.returnCacheDataElseFetch while Querying, a call is never made to the NetworkTransport class to return data even though the cache does not have a value for this Query yet. This happens when you have already completed a different query first.

To Reproduce
Steps to reproduce the behavior:

  1. Ensure no previous cache values exist (easy solution is to delete the app off device before this test)
  2. Run a query with this cache policy -- fetchIgnoringCacheData
  3. Run a DIFFERENT query with this cache policy -- returnCacheDataElseFetch
  4. See the second query coming back with nil, instead of fetching the data from the server

Expected behavior
If there has not been a query for that data yet, then it should fetch that data from the server and return instead of just returning nil from the cache

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.22 (Verified it is working properly in 2.6.21)
  • Dependency Manager: Cocoapods
  • Swift Version: My project is using swift 4.2 (AppSync dependencies are using swift 4.1.2)

Device Information (please complete the following information):

  • Device: Simulator and iPad mini (real device)
  • iOS Version: iOS 11.4, 11.3.1
  • Specific to simulators: no

Additional context
Everything works properly in 2.6.21, this issue only shows up when I upgrade my dependency to 2.6.22.

If you view the comments below, this bug has been isolated to a change in the Apollo GraphQLExecutor. commit c417b11

Additionally tests have been written in the comments below that demonstrate this issue.

Cache key not working with floats

Hi All,

Had fun and games with this one today, if I use a query and one of my parameters is a float it is not saving correctly in the cache. I finally managed to fix this by turning my float into a string but I seem to be the only person having this issue. Strange enough the float was in the format 363638, perhaps it needs more help in thinking its a float? The number was too long to be an int.

When I look in the SQLite DB the Query_Root key entry never puts my query in its record. Fixed this by making my parameter a string.

Thanks

Cocoapods is broken

After pod install, the error is the following:

pod install
Analyzing dependencies
[!] Unable to find a specification for AWSAppSync (~> 2.6.7)

[!] Automatically assigning platform ios with version 10.0 on target EventsApp because no platform was specified. Please specify a platform for this target in your Podfile. See https://guides.cocoapods.org/syntax/podfile.html#platform.

I think the readme should be updated too.

Carthage build reachability framework is outdated

Describe the bug
When building with Carthage the version of Reachability that is being downloaded is 3, but the sdk binary attempts to use functions from v4

dyld: Symbol not found: _$S12ReachabilityAAC24allowsCellularConnectionSbvpWvd Referenced from: /private/var/containers/Bundle/Application/54737AA0-D181-4133-830C-E863D0AA335B/Pear-DEV.app/Frameworks/AWSAppSync.framework/AWSAppSync Expected in: /private/var/containers/Bundle/Application/54737AA0-D181-4133-830C-E863D0AA335B/Pear-DEV.app/Frameworks/Reachability.framework/Reachability in /private/var/containers/Bundle/Application/54737AA0-D181-4133-830C-E863D0AA335B/Pear-DEV.app/Frameworks/AWSAppSync.framework/AWSAppSync

Environment(please complete the following information):

  • AppSync SDK Version: [2.6.22]
  • Dependency Manager: [Carthage]
  • Swift Version : [4.2]

Additional context
The problem seems to be the version specified in Cartfile (specified to be compatible with v 0.4.0). Needs an update to the latest

Subscription feature does not work immediately after installation. Only after closing app and reopening

Ported from issue opened by @jamesknowsbest: https://github.com/aws-samples/aws-mobile-appsync-events-starter-ios/issues/9

Issue: Subscription feature does not work immediately after installation. Only after closing app and reopening

steps to reproduce:

  • Install the app on a simulator
  • Once the app is installed create a event
  • Then select the event and create a comment for the event
  • This comment will not display in the view after creation

commenttable
eventtable

  • Close the app by double tapping the home button and swiping up on the app
  • reopen the app and create a new event.
  • Create a comment for this new event and this should appear in the view

more comments:

When adding a new event, the event was created in dynamoDB with eventid of 'f1b75cc2-4894-4f62-a1a4-2d4215d4025f' correctly, however the app stored '1B2C20C4-8832-40BF-B933-8CDBC98798CD' in it's local memory for that event for one reason or another

this means when adding comments to that event, it saves it in the DB with eventid of '1B2C20C4-8832-40BF-B933-8CDBC98798CD' which is an event that does not exist

as shown in the screenshots, the bottom two events do not appear as there is no associated eventid, however the top comment with the correct eventID does work

that was created after closing the app, and re-opening it

As far as I can tell, this happens because of where the app makes a UUID for the commentid table before processing the result of the query[1]. It then ignores the view and doesn't refresh it so the code which starts listening for new events doesn't fire[2].

[1] https://github.com/aws-samples/aws-mobile-appsync-events-starter-ios/blob/4ae387fdf6db962d7aa547e5fd9d1dd434c581d5/EventsApp/AddEventViewController.swift#L54
[2 ]https://github.com/aws-samples/aws-mobile-appsync-events-starter-ios/blob/4ae387fdf6db962d7aa547e5fd9d1dd434c581d5/EventsApp/AddEventViewController.swift#L70-L72

credit goes to my friend, Ken, for helping me find this bug

Memory leak when using AppSyncClient

Describe the bug
Memory leak continuously occurred when using AppSyncClient (especially when invokes mutation)

To Reproduce
Steps to reproduce the behavior:

  1. use appsyncClient.perform()

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
2018-10-06 7 52 24

Environment(please complete the following information):

  • AppSync SDK Version: 2.6.22
  • Dependency Manager: Cocoapods
  • Swift Version : 4.1

Device Information (please complete the following information):

  • Device: iPhone7, Simulator
  • iOS Version: iOS 11.4
  • Specific to simulators:

Additional context
Add any other context about the problem here.

how to handle the reconnection logics?

Currently I have my subscription code in viewDidload. The app's subscription won't work if app was in background for a few minutes the back to foreground. But I'm still able to fire mutation actions. How should I handle the reconnection to make the subscription work again?

AWSAppSyncSubscriptionWatcher cannot be deallocated until the connection state is able to be observed

A sample code like below:

let watcher1 = appsyncClient.subscribe(aTopic)
,watcher2 = appsyncClient.subscribe(anotherTopic)
//wait for a while 
logout() //logout will do something like watcher1.cancel(), watcher2.cancel()

when I start to call subscribe function, appsync will initialise a watcher. The problem is. If I call the 'cancel' method before mqtt connection state become connected/connecting or others, the watchers are not released.

The watchers are only able to be released if the connection status chanaged to a non-notobservable state

Don't see where ReachabilitySwift dependency is used

We're planning to use AppSync in our iOS app. But I have an issue with updating dependencies, since that our project uses new version of ReachabilitySwift, when AppSync uses older.

I checked imports of ReachabilitySwift and didn't find it.

So I suggest to remove it from podspec.

Automatic upload S3Object to bucket fails

Hey all,

This is a follow up to question I posted on the AWSAppSync forums and StackOverflow (links at bottom), which has some more detail on permissions and resolvers, but I'll summarize why I don't think that's an issue, and update the question here.

Basically, my app requires offline support, which AppSync provides almost perfectly, except for the file upload to an S3 bucket. I cannot get it to upload automatically. I intend to use User Pools, as that is my app's authentication method, but I have tried using IAM as well and cannot get the files to automatically upload. If I use S3TransferManager.default() and manually make the upload request using either authentication method, it succeeds every time, so I believe my permissions are correct. The S3Object is also added as an item attribute in DynamoDB as such:
"pdf": "{\"s3\":{\"key\":\"example.pdf\",\"bucket\":\"#####\",\"region\":\"us-west-2\"}}"

I set breakpoints in your AppSync code to check if the call to upload ever happens, and it doesn't seem to. This seems to be because, in line 508 in AWSAppSyncClient.swift (AppSync 2.6.15 using codegen w/ s3 wrapper argument), the check

if self.mutationRecord.type == .graphQLMutationWithS3Object { ...

always fails, so

appSyncClient.performMutationWithS3Object(...)

is not called, but instead

appSyncClient.send(...)

is called.

After a query, I am also able to successfully use

guard let s3Object = exampleThing?.pdf?.fragments.s3Object else { return }
appSyncClient?.s3ObjectManager?.download(s3Object: s3Object, toURL: fileURL!, completion: { (success, error) in
  ...
}

to download example.pdf (if I upload it to the S3 bucket myself, of course).

I followed your tutorials and created the S3Object type and S3ObjectInput in the schema, connected the appropriate resolvers, and it would seem set the right permissions. Do you guys know what I'm doing wrong here? Why is mutationRecord.type == .graphQLMutationWithS3Object not returning true or, more generally, why is the automatic upload to S3 not happening?

Currently, I've just created my own offline solution that uploads the files I need to S3 when Reachability goes from .none to either wifi or cellular, but it would be ideal if the upload was handled by AppSync at the same time it does the offline mutation.

Any ideas? Thanks!

PS: Also, and this could just be a breakpoint thing, mutationRecord.type shows up as <invalid> to my debugging window, while the other variables are 'some', etc. And mutationRecord.s3ObjectInput is 'none' (this breakpoint was set during a CreateThingMutation, after checking mutationRecord.type fails, inside the 'else' statement that calls appSyncClient.send(...)).

AWS AppSync Forum question:
https://forums.aws.amazon.com/message.jspa?messageID=847113
S.O. question:
https://stackoverflow.com/questions/50050340/aws-appsync-unable-to-upload-s3object-to-bucket-automatically-with-cognito-use

No way to disable offline buffer

Hi,

Reading thought the documentation and code, i can't find a way to disable the offline stuff. My client is pretty simple and this complexity is mucking it up.

Current behavior:
Making a network call to AppSync while offline does not invoke callback, presumably this is buffered somewhere?

Desired behavior:
Making a network call to AppSync while offline fails - an error message is sent to callback

Thanks for considering this.
-Michael

No way to clear client cache

Ok, so i'm struggling with this case:

i have a query that does "get info about the current user". It doesn't take an id as a parameter, instead depends on the users context.identity.cognitoIdentityId (iam auth).

The problem i have is: if you do that call, i believe it is caching the response, then if i sign out and sign back in (as a different user), i get the old user's information when i do the same call.

Perhaps i can play with the cache keys (so it contains the user id in it)? - i'm not sure how to set this:
appSyncClient?.apolloClient?.cacheKeyForObject = { $0["id"] }

I didn't see documentation for this method, but maybe i'm missing it?

Alternatively - it would be great to just expose appSyncClient.store.clearCache (i think this is a thing here: https://github.com/apollographql/apollo-ios/blob/master/Sources/Apollo/ApolloStore.swift)

Sorry if i'm not making sense - I'll be happy to go into more detail if needed.

AWSAppSyncSubscriptionWatcher cancel method block main thread when there are about 20 watchers(subscriptions)

Whenever my app entered background, I cancelled all the subscriptions in background to reduce the network traffic. When app went to foreground again, I would re-subscribe them. But What I found is: this is a very heavy process. If there are more than 20 subscribers(which is possible for a chat app), it takes time to cancel them all. If I went to foreground immediately before all subscribers finished their cancelation works, the app's UI will be blocked for a while. I have to wait for all of them finish the cancelation to avoid blocking the ui.

For short, if I entered background then back to foreground quite fast and there are about 20 subscribers, the cancelations and subscriptions might happen simultaneously, which blocks the UI. I also checked the cancel method, seems like it has a very heavy workload although it's not an async method. I tried to print and find that all the 20 cancelations will take about 5-7 seconds to finish. Would be very appreciated if you could provide me some help. By the way, I've applied the pull request #28 and #34 to my own fork so I'm not sure whether this issue happened in the original repo. I cannot revert back because I have some of my own commits which expose the connection state to the user of the app.

cannot invoke a lambda function in different region

I configured appsync in apnortheast1 region and a lambda function in apsoutheast1. I selected 'create role' with the role automatically created. After that I got such error on client side:
❤️ ERROR errs: [The role defined for the function cannot be assumed by Lambda. (Service: AWSLambda; Status Code: 403; Error Code: AccessDeniedException; Request ID: bdd72051-4e81-11e8-bf27-7b4058a38dfb)
I tried to invoke a function created in apnortheast1 too with no problem.

How do I create the config file for connecting to appsync with swift using user pools

Hi

Could you please provide a best practice example on how to create the config file for user pools. Presently I am passing self on app delegate as the argument and conforming to the protocol to get the token but not sure if this is the way to go or to create a new class. Thanks.
In AppDelegate

let appSyncConfig = try AWSAppSyncClientConfiguration(url: AppSyncEndpointURL, serviceRegion: AppSyncRegion, userPoolsAuthProvider: self)
self.appSyncClient = try AWSAppSyncClient(appSyncConfig: appSyncConfig)
let user = pool.currentUser()
user?.getSession().continueOnSuccessWith(block: { (task) -> Any? in
    let getSessionResult = task.result
    self.idToken = getSessionResult?.idToken?.tokenString
    
    return nil
})
extension AppDelegate: AWSCognitoUserPoolsAuthProvider {
    func getLatestAuthToken() -> String {
        if idToken != nil {
            return idToken!
        } else {
            return ""
        }
    }
}

MQTT Connection Status Looks Strange

I've used appsync as a chat app, thus I have to observe the connection status for each conversation, I tried to fork this repo and exposed the connection status to my main app,

As shown below, I have two conversations with dialog ids 10028 and 10029. I have made two subscriptions for each of them, as you can see from the log, 10028 subscribed first, but it keep connecting even it was connected before.

11:23:07 💙 INFO all connection status: [""]
11:23:07 💙 INFO all connection status: ["", ""]
11:23:08 💙 INFO all connection status: ["", "10028-connecting..."]
11:23:09 💙 INFO all connection status: ["", "10028-connected"]
11:23:15 💙 INFO all connection status: ["", "10028-connecting..."]
11:23:15 💙 INFO all connection status: ["10029-connecting...", "10028-connecting..."]
11:23:16 💙 INFO all connection status: ["10029-connected", "10028-connecting..."]
11:23:16 💙 INFO all connection status: ["10029-connected", "10028-connected"]

If there are more than 2 conversations, I found that one connected conversation will keep changing from connected to connecting then to connected again during other subscribers' connection status changes. Do you have any idea about this? Appreciated if you could provide me some help!

Setting s3ObjectManager to AWSS3TransferUtility.default() fails

So according to the docs I should be able to set

let appSyncConfig = try AWSAppSyncClientConfiguration(url: AppSyncEndpointURL,
                                                      serviceRegion: AppSyncRegion,
                                                      credentialsProvider: credentialsProvider,
                                                      databaseURL:databaseURL,
                                                      s3ObjectManager: AWSS3TransferUtility.default())

However when attempting to set this with the user pool as in

            let appSyncConfig = try AWSAppSyncClientConfiguration.init(url: AppSyncEndpointURL, serviceRegion: AppSyncRegion, userPoolsAuthProvider: CognitoUserPoolsAuthProvider(pool: pool), urlSessionConfiguration: URLSessionConfiguration.default, databaseURL: databaseURL, connectionStateChangeHandler: nil, s3ObjectManager: AWSS3TransferUtility.default() as! AWSS3ObjectManager, presignedURLClient: nil)

It will just complain that Could not cast value of type 'AWSS3TransferUtility' (0x114bb1830) to 'AWSAppSync.AWSS3ObjectManager' (0x114bb1858).

How do I create the s3ObjectManager to pass in?

uploading file to s3 using appsync with lambda as datasource

I am following the following tutorial to upload s3 images along with other message details to my s3 bucket using appsync:

https://docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app-ios.html

The example is using a resolver for a dynamoDB datasource. How can I correctly setup the resolver when using a lambda function as my datasource (amazon aurora). This is presently my resolver which works fine for inserting data in my data source but does not upload the image data file to my s3 bucket:

{
"version": "2017-02-28",
"operation": "Invoke",
"payload": {
"field": "createMessage",
"arguments": $utils.toJson($context.arguments)
}
}

Also what is the localUri? and how is that different from the localUrl string that I can use to identify my file locally?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.