GithubHelp home page GithubHelp logo

aws-amplify / amplify-swift Goto Github PK

View Code? Open in Web Editor NEW
427.0 427.0 185.0 33.96 MB

A declarative library for application development using cloud services.

License: Apache License 2.0

Swift 97.01% Ruby 0.02% Objective-C 0.01% Shell 0.37% C 2.56% Mermaid 0.02% JavaScript 0.01%
aws aws-amplify ios swift

amplify-swift's Introduction

AWS Amplify

current aws-amplify package version weekly downloads GitHub Workflow Status (with event) code coverage join discord

Reporting Bugs / Feature Requests

Open Bugs Feature Requests Closed Issues

Note aws-amplify 6 has been released. If you are looking for upgrade guidance click here

AWS Amplify is a JavaScript library for frontend and mobile developers building cloud-enabled applications

AWS Amplify provides a declarative and easy-to-use interface across different categories of cloud operations. AWS Amplify goes well with any JavaScript based frontend workflow and React Native for mobile developers.

Our default implementation works with Amazon Web Services (AWS), but AWS Amplify is designed to be open and pluggable for any custom backend or service.

Visit our documentation site to learn more about AWS Amplify. Please see the Amplify JavaScript page for information around the full list of features we support.

Features

Category AWS Provider Description
Authentication Amazon Cognito APIs and Building blocks to create Authentication experiences.
Analytics Amazon Pinpoint Collect Analytics data for your application including tracking user sessions.
REST API Amazon API Gateway Sigv4 signing and AWS auth for API Gateway and other REST endpoints.
GraphQL API AWS AppSync Interact with your GraphQL or AWS AppSync endpoint(s).
DataStore AWS AppSync Programming model for shared and distributed data, with simple online/offline synchronization.
Storage Amazon S3 Manages content in public, protected, private storage buckets.
Geo (Developer preview) Amazon Location Service Provides APIs and UI components for maps and location search for JavaScript-based web apps.
Push Notifications Amazon Pinpoint Allows you to integrate push notifications in your app with Amazon Pinpoint targeting and campaign management support.
Interactions Amazon Lex Create conversational bots powered by deep learning technologies.
PubSub AWS IoT Provides connectivity with cloud-based message-oriented middleware.
Internationalization --- A lightweight internationalization solution.
Cache --- Provides a generic LRU cache for JavaScript developers to store data with priority and expiration settings.
Predictions Various* Connect your app with machine learning services like NLP, computer vision, TTS, and more.
  • Predictions utilizes a range of Amazon's Machine Learning services, including: Amazon Comprehend, Amazon Polly, Amazon Rekognition, Amazon Textract, and Amazon Translate.

Getting Started

AWS Amplify is available as aws-amplify on npm.

To get started pick your platform from our Getting Started home page

Notice:

Amplify 6.x.x has breaking changes. Please see the breaking changes on our migration guide

Amplify 5.x.x has breaking changes. Please see the breaking changes below:

  • If you are using default exports from any Amplify package, then you will need to migrate to using named exports. For example:

    - import Amplify from 'aws-amplify';
    + import { Amplify } from 'aws-amplify'
    
    - import Analytics from '@aws-amplify/analytics';
    + import { Analytics } from '@aws-amplify/analytics';
    // or better
    + import { Analytics } from 'aws-amplify';
    
    - import Storage from '@aws-amplify/storage';
    + import { Storage } from '@aws-amplify/storage';
    // or better
    + import { Storage } from 'aws-amplify';
  • Datastore predicate syntax has changed, impacting the DataStore.query, DataStore.save, DataStore.delete, and DataStore.observe interfaces. For example:

    - await DataStore.delete(Post, (post) => post.status('eq', PostStatus.INACTIVE));
    + await DataStore.delete(Post, (post) => post.status.eq(PostStatus.INACTIVE));
    
    - await DataStore.query(Post, p => p.and( p => [p.title('eq', 'Amplify Getting Started Guide'), p.score('gt', 8)]));
    + await DataStore.query(Post, p => p.and( p => [p.title.eq('Amplify Getting Started Guide'), p.score.gt(8)]));
  • Storage.list has changed the name of the maxKeys parameter to pageSize and has a new return type that contains the results list. For example:

    - const photos = await Storage.list('photos/', { maxKeys: 100 });
    - const { key } = photos[0];
    
    + const photos = await Storage.list('photos/', { pageSize: 100 });
    + const { key } = photos.results[0];
  • Storage.put with resumable turned on has changed the key to no longer include the bucket name. For example:

    - let uploadedObjectKey;
    - Storage.put(file.name, file, {
    -   resumable: true,
    -   // Necessary to parse the bucket name out to work with the key
    -   completeCallback: (obj) => uploadedObjectKey = obj.key.substring( obj.key.indexOf("/") + 1 )
    - }
    
    + let uploadedObjectKey;
    + Storage.put(file.name, file, {
    +   resumable: true,
    +   completeCallback: (obj) => uploadedObjectKey = obj.key
    + }
  • Analytics.record no longer accepts string as input. For example:

    - Analytics.record('my example event');
    + Analytics.record({ name: 'my example event' });
  • The JS export has been removed from @aws-amplify/core in favor of exporting the functions it contained.

  • Any calls to Amplify.Auth, Amplify.Cache, and Amplify.ServiceWorker are no longer supported. Instead, your code should use the named exports. For example:

    - import { Amplify } from 'aws-amplify';
    - Amplify.configure(...);
    - // ...
    - Amplify.Auth.signIn(...);
    
    + import { Amplify, Auth } from 'aws-amplify';
    + Amplify.configure(...);
    + // ...
    + Auth.signIn(...);

Amplify 4.x.x has breaking changes for React Native. Please see the breaking changes below:

  • If you are using React Native (vanilla or Expo), you will need to add the following React Native community dependencies:
    • @react-native-community/netinfo
    • @react-native-async-storage/async-storage
// React Native
yarn add aws-amplify amazon-cognito-identity-js @react-native-community/netinfo @react-native-async-storage/async-storage
npx pod-install

// Expo
yarn add aws-amplify @react-native-community/netinfo @react-native-async-storage/async-storage

Amplify 3.x.x has breaking changes. Please see the breaking changes below:

If you can't migrate to aws-sdk-js-v3 or rely on [email protected], you will need to import it separately.

  • If you are using exported paths within your Amplify JS application, (e.g. import from "@aws-amplify/analytics/lib/Analytics") this will now break and no longer will be supported. You will need to change to named imports:

    import { Analytics } from 'aws-amplify';
  • If you are using categories as Amplify.<Category>, this will no longer work and we recommend to import the category you are needing to use:

    import { Auth } from 'aws-amplify';

DataStore Docs

For more information on contributing to DataStore / how DataStore works, see the DataStore Docs

amplify-swift's People

Contributors

5d avatar ameter avatar ashiemke avatar atierian avatar brennanmke avatar daohoangson avatar dependabot[bot] avatar diegocstn avatar dnys1 avatar dpilch avatar drochetti avatar harsh62 avatar haverchuck avatar iartemiev avatar jcjimenez avatar jpeddicord avatar kneekey23 avatar lawmicha avatar manaswi223 avatar mlabieniec avatar muniekmg avatar palpatim avatar phantumcode avatar royjit avatar ruiguoamz avatar ruisebas avatar siegerts avatar thisisabhash avatar wooj2 avatar yeung-wah 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

amplify-swift's Issues

List Usability - List only returns up to 1000

List API usability testing is required.

Currently in line with JS library; uses LLC s3 to retrieve list of keys.

According to S3 documentation, only returns 1000 items.

This issue is test usability of List API, document any limitations (like the 1000 returned items) and make any changes necessary to the usability that we want

Support enums in code generated models

Given the following type:

public struct MutationEvent: Model {
    public enum MutationType: String, Codable {
        case create
        case update
        case delete
    }

    public let id: Identifier
    public let modelName: String
    public let json: String
    public let mutationType: MutationType
    public let createdAt: Date

    public init(id: Identifier = UUID().uuidString,
                modelName: String,
                data: String,
                mutationType: MutationType,
                createdAt: Date = Date()) {
        self.id = id
        self.modelName = modelName
        self.json = data
        self.mutationType = mutationType
        self.createdAt = createdAt
    }
}

extension MutationEvent {
    // MARK: - CodingKeys

    public enum CodingKeys: String, ModelKey {
        case id
        case modelName
        case json
        case mutationType
        case createdAt
    }

    public static let keys = CodingKeys.self

    // MARK: - ModelSchema

    public static let schema = defineSchema { definition in
        let mutation = MutationEvent.keys

        definition.attributes(.isSyncable, .isSystem)

        definition.fields(
            .id(),
            .field(mutation.modelName, is: .required, ofType: .string),
            .field(mutation.json, is: .required, ofType: .string),
            .field(mutation.mutationType,
                   is: .required,
                   ofType: .enum(type: MutationType.self)),
            .field(mutation.createdAt, is: .required, ofType: .dateTime)
        )
    }
}

Registering the type as a model fails:

2019-11-18 16:19:40.219199-0800 AmplifyTestApp[21061:3952734] Fatal error: Model with name MutationType could not be found.: file /Users/schmelte/src/github-repos/amplify-ios/Amplify/Categories/DataStore/Model/ModelSchema+Definition.swift, line 70

It looks like it's not going to be as simple as just detecting the type in ModelField.typeDefinition, since the incoming type on the field is MutationType, and I don't see any path to find that it's actually an enum.

Handle plural in list and sync GraphQL queries

Unfortunately there's no consistent behavior in the current GraphQL transformer for plural handling. The list queries just append an "s" whereas the sync queries use the actual plural form: listPersons vs syncPeople. This will be changed in the future and we will need to handle the fallback logic accordingly.

Originally posted by @drochetti in #175

Audit thread/queue usage

We do a lot of work on DispatchQueues (good), but don't assign target queues to them (bad), which could result in an explosion of threads for some cases (e.g., Hub, which uses a SynchronizedDictionary for each channel, each with its own concurrency queue).

We need to audit our use of DispatchQueues and make sure we're only using concurrent queues where needed, and set targets on serial queues where appropriate.

Enable TransferAcceleration

Investigate:
JS experience, how it is currently enabled by the developer. Can transferAcceleration be configured on per request basis? ie. only enable for downloads and not uploads, for some reason. Native experience, how is it enabled on transferUtility now?

CLI changes

  • Ask to enable transferAcceleration
  • If Yes:
  1. apply some settings on the bucket to allow transfer acceleration
    2 add transferAcceleration: true into amplifyconfiguration.json

Library changes
Extract TransferAcceleration and propagate into setting up dependencies (transferUtility/s3)

StorageService Unit testing - adding Mocks and Tests

Need to add more unit tests for the AWS3StorageService class. Some happy path cases can be added now, while some failure cases can come after finalizing on error mapping. ie. Mock dependency to return a failed task with HttpStatus error with code 403, verify that the StorageError coming from AWS3StorageService is AccessDenied. etc.

JSON deserialization fails for timestamps without fractional seconds

To reproduce:

  • Use a schema with an AWSDateTime field
  • Create a record with a valid ISO8601 date, but without a fractional second, as in: 2019-11-27T03:10:52Z
  • Attempt to deserialize the record, as by doing a "get" query operation

Expected results:

  • The record deserializes properly into an object

Actual results:

  • Transformation error:
    dataCorrupted(Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 269", intValue: 269), CodingKeys(stringValue: "updatedAt", intValue: nil)], debugDescription: "Date string does not match format expected by formatter.", underlyingError: nil))
    

API Category -Support two different default endpoints configured

the caveat here is that we are looking for a single endpoint config when apiName is not passed in and throws configuration error if more than one (since it does not know which to pick). developer needs to call the right APIs (get/post/post/delete or mutate/query/subscribe) for the right endpoint (api gateway endpoints or appsync graphql endpoints).

The final solution should include a proposal for CLI team to add a type of endpoint. then our code will look under the graphql type of restAPI types and find the single one. or if it finds more than one, return error

Originally posted by @lawmicha in #93

Define the depth of eager loaded associations

That's a good question and the part I struggled with. Right now the depth is not specified. This logic will even break in case or circular references.

How to decode missing properties to a Struct that require them? I'm having a hard time keeping the data model types consistent but optimize for performance and different use cases of associations (lazy vs eager, required vs optional)

Originally posted by @drochetti in #164

Verify SQLite limit to bind variables

Heaven forbid we ever hit it, but do I remember that SQLite has a limit on the number of bind variables on the order of 1,000? Might be worth verifying that and including it the documentation

Originally posted by @palpatim in #116

API Plugin Remove constants file

can you expand on this a bit? I am creating a structure for getting different url request constants like

struct URLRequestContants {
    static let appSyncServiceName = "appsync"

    struct Header {
        static let xAmzDate = "X-Amz-Date"
        static let contentType = "Content-Type"
        static let userAgent = "User-Agent"
        static let xApiKey = "x-api-key"
    }

    struct ContentType {
        static let applicationJson = "application/json"
    }

    struct UserAgent {
        static let amplify = "amplify-ios/0.0.1 Amplify"
    }
}

maybe this just needs a renaming? or should i change the structure here as well?

Originally posted by @lawmicha in https://github.com/_render_node/MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzEyNTc2OTcx/pull_request_reviews/more_threads

TrackEvents and AppSessionTracker

  • a few missed unit tests on the extensions of AWSPinpointEndpointProfile, AWSPinpointEndpointProfileLocation, AWSPinpointEvent (may iterate on this PR for this)
  • Better error mapping for pinpoint service errors
  • Better validation on global properties like total number of properties
  • Investigate setting location in IdentifyUser call
  • integration tests
  • [P0] FlushEventsTracker
  • [P0] AppSessionTracker

Update Cocoapods Podfile with dependencies as I add/remove categories in the CLI

When setting up an Amplify project for iOS, I would like for the CLI to automatically update the Cocoapods Podfile as I add or remove categories in the CLI.

For example, if I want to add Auth to my app with the default "basic auth", there are known AWS SDK dependencies that need to be added to my Podfile to install the AWS SDK on the client.

Here's the scenario:
Amplify init as an iOS project
amplify add auth - select the default option which is just basic auth (username/password)
amplify push
The CLI updates my awsconfiguration.json with any new endpoints.

At this point I need to go back to the iOS docs and figure out what dependencies are needed for adding the auth SDK to my app. In the case of the default auth here, the following three dependencies should be added to my Podfile:

Amazon Cognito User Pools (Basic Auth)

pod 'AWSUserPoolsSignIn', '~> 2.8.0'   # Optional dependency required to use drop-in UI

Shared auth components

pod 'AWSMobileClient', '~> 2.8.0'    # Required dependency for Auth with AWS SDK for iOS
pod 'AWSAuthUI', '~> 2.8.0'          # (Optional) dependency is required when using drop-in UI

So, with this feature implemented, after an amplify push, the Podfile is automatically updated and I simply run pod install.

Improve SQL Result Set to Model conversion

this gave a huge performance boost to SQL result set -> model conversion. I believe this is still need more testing and most likely there are more performance improvements to be made, but I would say that so far so good. I query of 1300 rows, including a joint table with 50 rows took less than 80ms to de-serialize.

That said, I'm not 100% happy with this logic, readability and caching strategy

Originally posted by @drochetti in #153

API Plugin Interceptors Clean up

is this blocking? If interceptors execute asynchronous operations I believe they should be asynchronous by nature. I believe we should avoid using any type of semaphores to turn asynchronous operations into synchronous ones unless strictly necessary.

So instead of:

func intercept(_ request: URLRequest) throws -> URLRequest

The API could be:

func intercept(_ request: URLRequest, next: URLRequestInterceptor) throws

// or in a functional way where the `next` refers to the next interceptors `intercept` function

func intercept(_ request: URLRequest, next: (URLRequest) -> Void) throws

Once an interceptor is done processing an URLRequest, it calls next to continue the interceptor chain.

Originally posted by @drochetti in https://github.com/_render_node/MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzEyMjY0MzE4/pull_request_reviews/more_threads

API Plugin Configuration clean up

One of the intents of the AWSAuthorizationConfiguration is to obviate the need for config objects to directly know about auth service. Let's talk about this to see if we can remove the dependency. Perhaps we can create a configuration factory with the auth service, that can then be used to instantiate configurations when needed.

Originally posted by @palpatim in https://github.com/_render_node/MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzEyNTc2OTcx/pull_request_reviews/more_threads

Make AnyModel.schema fail with fatalError

Per discussion #134 (comment)

We should investigate whether we can make the static AnyModel.schema property getter fail with a fatalError("AnyModel.schema is not supported. Use the instance property, which reflects the schema of the underlying instance.")

Hub related documentation

we may have to link "via the Hub" to the Hub category or even to a guide. Not something that needs to be addressed right now but maybe we could create a task to track it? We will need to do it not only here, but it just occurred to me, that we should assume that some devs might now know what "via the Hub" means, or how to do it, when they are reading the docs of other categories.

Originally posted by @drochetti in #93

Encapsulate model registry

Current implementation of the model registry is a top level var accessible via top-level un-namespaced methods. Need to encapsulate this in a type, probably DataStore.

Should default access level be 'public' ?

[Storage] Should default access level be 'public'

Capturing some of the TODO's in an Issue. In JS, it is by default public: https://aws-amplify.github.io/docs/js/storage#file-access-levels

I find the 'public' directory kind of odd use case, i'm not sure when we would ever upload to a public directory since anyone can delete from there. I could extract someone's amplifyconfiguration.json, reconstruct my own app using those configuration values, and call remove on all of the keys in the public folder

Analytics Specific events like AnalyticsRevenueEvent and AnalyticsScreenEvent

Add revenue event

public struct AnalyticsRevenueEvent: AnalyticsEvent {

    /// Name of the event
    public var name: String

    /// Identifier of the product
    public var productId: String

    /// Value of the product
    public var value: Double

    /// Revenue of the sale
    public var revenue: Double

    /// Amount sold of the product
    public var quantity: Int

    /// Currency of the sale
    public var currency: String

    /// Properties of the event
    public var properties: [String: AnalyticsPropertyValue]?

    public init(name: String,
                productId: String,
                value: Double,
                revenue: Double,
                quantity: Int,
                currency: String,
                properties: [String: AnalyticsPropertyValue]? = nil) {
        self.name = name
        self.productId = productId
        self.value = value
        self.revenue = revenue
        self.quantity = quantity
        self.currency = currency
        self.properties = properties
    }
}

Rename Category/PluginBehavior classes

Rename existing classes to agreed upon class names to be in line with Android. Need to check where we have defined this structure and naming, cross check with Android's code base.

off the top of my head;

  1. StorageCategory to Storage
  2. ClientBehavior to CategoryyBehavior

Make Logging and Hub categories available at initialization

Right now, it is impossible for callers to use the Logging or Hub categories until we've called Amplify.configure. This needs to be changed so that default plugins can use the logger and hub during initialization and configuration flows.

We've made partial progress toward that--the Hub and Logging categories are the first to be configured, but that isn't sufficient for (for example) setting up a Plugin that uses the logger during its initialization.

Separate debug description from string value for code generated strings

Currently, GraphQLDocuments and SQLStatements generate their code with nicely formatted, indented, human-readable code. That makes debugging easier, but is potentially costly, and definitely unnecessary, for machine-to-machine communication. We should separate the generated code into human-readable and machine-consumable components, perhaps by using debugDescription to provide custom representations for human readable use cases.

API Plugin SubscriptionOperation Implementation of subscription management

ConnectionProvider provides events for connections and subscriptions. in this case, only a SubscriptionConnection cares about the ConnectionProvider events, while holding onto all of the subscribers for the connection.

for example, when connection provider sends a connected event, connection will listen to this and react to this by checking if there are any subscribers in memory which need to start the subscription process.

when we move over to the case where SubscriptionConnection creates SubscriptionOperations which manage their own subscription to the connection provider, then there is see a need to register multiple listeners on the connection provider.

in the SubscriptionConnection and SubscriptionOperation model. the SubscriptionConnection holds a queue of subscriptionOperations. SubscriptionOperation is instantiated with the connection provider. Connection registers a listener with the connection provider and reacts to connection related events such as disconnected, try reconnect. Subscriptions also register their own listener with the connection provider and reacts to the connection provider events in the way that is relevant for them. ie. when disconnected event comes, it is responsible for setting its own subscription state to disconnected. when subscriptionDisconnect event comes, it is responsible for removing the listener from the connection provider, and calling finish() on the operation (which then removes it from the queue inside the SubscriptionConnection.

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.