├── .github
├── CODEOWNERS
└── stale.yml
├── .gitignore
├── IoT-Sample
└── Swift
│ ├── IoTSampleSwift.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── IoTSampleSwift.xcworkspace
│ └── contents.xcworkspacedata
│ ├── IoTSampleSwift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── first.imageset
│ │ │ ├── Contents.json
│ │ │ └── first.pdf
│ │ └── second.imageset
│ │ │ ├── Contents.json
│ │ │ └── second.pdf
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── ConfigurationViewController.swift
│ ├── ConnectionViewController+Websocket.swift
│ ├── ConnectionViewController.swift
│ ├── Constants.swift
│ ├── Info.plist
│ ├── IoTSampleSwift.entitlements
│ ├── IoTSampleTabBarController.swift
│ ├── PublishViewController.swift
│ └── SubscribeViewController.swift
│ ├── Podfile
│ ├── README.md
│ └── awsconfiguration.json
├── LICENSE
├── Lex-Sample
├── ObjC
│ ├── Lex-Sample.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ ├── Lex-Sample
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── ChatViewController.h
│ │ ├── ChatViewController.m
│ │ ├── Constants.h
│ │ ├── Constants.m
│ │ ├── Info.plist
│ │ ├── TableViewController.h
│ │ ├── TableViewController.m
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ └── main.m
│ └── Podfile
└── Swift
│ ├── .gitignore
│ ├── LexSwift.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── LexSwift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── ChatViewController.swift
│ ├── Constants.swift
│ ├── Info.plist
│ ├── Main.storyboard
│ ├── StringExtension.swift
│ ├── TableViewController.swift
│ └── VoiceChatViewController.swift
│ ├── Podfile
│ ├── README.md
│ └── awsconfiguration.json
├── NOTICE
├── Polly-Sample
└── Swift
│ ├── Podfile
│ ├── PollySample.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── PollySample.xcworkspace
│ └── contents.xcworkspacedata
│ ├── PollySample
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── ViewController.swift
│ ├── README.md
│ └── awsconfiguration.json
├── README.md
└── S3TransferUtility-Sample
├── Objective-C
├── Podfile
├── README.md
├── S3BackgroundTransferSampleObjC
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Constants.h
│ ├── Constants.m
│ ├── FirstViewController.h
│ ├── FirstViewController.m
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── first.imageset
│ │ │ ├── Contents.json
│ │ │ └── first.pdf
│ │ └── second.imageset
│ │ │ ├── Contents.json
│ │ │ └── second.pdf
│ ├── Info.plist
│ ├── Launch Screen.storyboard
│ ├── SecondViewController.h
│ ├── SecondViewController.m
│ ├── TemplateIcon2x.png
│ └── main.m
├── S3TransferUtilitySampleObjC.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
└── S3TransferUtilitySampleObjC.xcworkspace
│ └── contents.xcworkspacedata
└── Swift
├── .gitignore
├── Podfile
├── README.md
├── S3BackgroundTransferSampleSwift
├── AppDelegate.swift
├── Base.lproj
│ └── Main.storyboard
├── Constants.swift
├── DownloadViewController.swift
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── first.imageset
│ │ ├── Contents.json
│ │ └── first.pdf
│ └── second.imageset
│ │ ├── Contents.json
│ │ └── second.pdf
├── Info.plist
├── Launch Screen.storyboard
└── UploadViewController.swift
├── S3TransferUtilitySampleSwift.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── S3TransferUtilitySampleSwift.xcworkspace
└── contents.xcworkspacedata
├── S3TransferUtilitySampleSwiftUITests
├── Info.plist
└── S3TransferUtilitySampleSwiftUITests.swift
└── awsconfiguration.json
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @awslabs/amplify-ios
2 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | # Setting this to 100 years, because we do not want to automatically mark issues as stale
3 | daysUntilStale: 36500
4 | # Number of days of inactivity before a stale issue is closed
5 | daysUntilClose: 7
6 | # Label to use when marking an issue as stale
7 | staleLabel: closing-soon-if-no-response
8 | # Comment to post when marking an issue as stale. Set to `false` to disable
9 | markComment: >
10 | This issue has been automatically marked as stale because it has not had
11 | recent activity. It will be closed if no further activity occurs. Thank you
12 | for your contributions.
13 | # Comment to post when closing a stale issue. Set to `false` to disable
14 | closeComment: >
15 | This issue has been automatically closed because of inactivity.
16 | Please open a new issue if are still encountering problems.
17 | # Limit to only `issues` or `pulls`
18 | only: issues
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS generated files #
2 | ######################
3 | .DS_Store
4 | .DS_Store?
5 | ._*
6 | .Spotlight-V100
7 | .Trashes
8 | Icon?
9 | ehthumbs.db
10 | Thumbs.db
11 | src/Documentation/*
12 | src/docs/docset/*
13 | src/docs/docset-installed.txt
14 | src/aws-ios-sdk-*.zip
15 |
16 | # Xcode generated files #
17 | ######################
18 | xcuserdata
19 | *.xccheckout
20 | *.xcscmblueprint
21 |
22 | # Patched code #
23 | ######################
24 | *.bak
25 |
26 | # Built assets #
27 | ######################
28 | build
29 | buildFramework
30 | AWS*.framework
31 |
32 | # Stuff that can't be committed #
33 | ######################
34 | credentials.json
35 | Podfile.lock
36 | **/Pods
37 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSCore
18 |
19 | @UIApplicationMain
20 | class AppDelegate: UIResponder, UIApplicationDelegate {
21 |
22 | var window: UIWindow?
23 |
24 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
25 | // Override point for customization after application launch.
26 |
27 | // Setting up logging to xcode console.
28 | AWSDDLog.sharedInstance.logLevel = .debug
29 | AWSDDLog.add(AWSDDTTYLogger.sharedInstance)
30 |
31 | return true
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "first.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/first.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/first.pdf
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "second.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/second.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/second.pdf
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/ConfigurationViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSIoT
18 |
19 | class ConfigurationViewController: UIViewController, UITextFieldDelegate {
20 |
21 | @IBOutlet weak var deleteCertificateButton: UIButton!
22 | @IBOutlet weak var topicTextField: UITextField!
23 |
24 | @IBAction func deleteCertificateButtonPressed(_ sender: AnyObject) {
25 | let actionController: UIAlertController = UIAlertController( title: nil, message: nil, preferredStyle: .actionSheet)
26 | let cancelAction: UIAlertAction = UIAlertAction( title: "Cancel", style: .cancel) { action -> Void in
27 | }
28 |
29 | actionController.addAction( cancelAction )
30 |
31 | let okAction: UIAlertAction = UIAlertAction( title: "Delete", style: .default) { action -> Void in
32 | print( "deleting identity...")
33 |
34 | // To delete an identity created via the API:
35 | //
36 | // 1) Set the certificate's status to 'inactive'
37 | // 2) Detach the policy from the certificate
38 | // 3) Delete the certificate
39 | // 4) Remove the keys and certificate from the keychain
40 | // 5) Delete user defaults
41 | //
42 | // To delete an identity created via a PKCS12 file in the bundle:
43 | //
44 | // 1) Remove the keys and certificate from the keychain
45 | // 2) Delete user defaults
46 |
47 | let defaults = UserDefaults.standard
48 | let certificateId = defaults.string( forKey: "certificateId")
49 | let certificateArn = defaults.string( forKey: "certificateArn")
50 |
51 | if certificateArn != "from-bundle" && certificateId != nil
52 | {
53 | let iot = AWSIoT.default()
54 |
55 | let updateCertificateRequest = AWSIoTUpdateCertificateRequest()
56 | updateCertificateRequest?.certificateId = certificateId
57 | updateCertificateRequest?.latestStatus = .inactive
58 |
59 | iot.updateCertificate( updateCertificateRequest! ).continueWith(block:{ (task) -> AnyObject? in
60 |
61 | if let error = task.error {
62 | print("failed: [\(error)]")
63 | }
64 | print("result: [\(String(describing: task.result))]")
65 | if (task.error == nil)
66 | {
67 | // The certificate is now inactive; detach the policy from the certificate.
68 | let certificateArn = defaults.string( forKey: "certificateArn")
69 | let detachPolicyRequest = AWSIoTDetachPrincipalPolicyRequest()
70 | detachPolicyRequest?.principal = certificateArn
71 | detachPolicyRequest?.policyName = POLICY_NAME
72 |
73 | iot.detachPrincipalPolicy(detachPolicyRequest!).continueWith(block: { (task) -> AnyObject? in
74 | if let error = task.error {
75 | print("failed: [\(error)]")
76 | }
77 | print("result: [\(String(describing: task.result))]")
78 | if (task.error == nil)
79 | {
80 | // The policy is now detached; delete the certificate
81 | let deleteCertificateRequest = AWSIoTDeleteCertificateRequest()
82 | deleteCertificateRequest?.certificateId = certificateId
83 |
84 | iot.deleteCertificate(deleteCertificateRequest!).continueWith(block: { (task) -> AnyObject? in
85 |
86 | if let error = task.error {
87 | print("failed: [\(error)]")
88 | }
89 | print("result: [\(String(describing: task.result))]")
90 | if (task.error == nil)
91 | {
92 | // The certificate has been deleted; now delete the keys and certificate from the keychain.
93 | if (AWSIoTManager.deleteCertificate() != true)
94 | {
95 | print("error deleting certificate")
96 | }
97 | else
98 | {
99 | defaults.removeObject(forKey: "certificateId")
100 | defaults.removeObject(forKey: "certificateArn")
101 | DispatchQueue.main.async {
102 | self.tabBarController?.selectedIndex = 0
103 | }
104 | }
105 | }
106 | return nil
107 | })
108 | }
109 | return nil
110 | })
111 | }
112 | return nil
113 | })
114 |
115 | }
116 | else if certificateArn == "from-bundle"
117 | {
118 | // Delete the keys and certificate from the keychain.
119 | if (AWSIoTManager.deleteCertificate() != true)
120 | {
121 | print("error deleting certificate")
122 | }
123 | else
124 | {
125 | defaults.removeObject(forKey: "certificateId")
126 | defaults.removeObject(forKey: "certificateArn")
127 | DispatchQueue.main.async {
128 | self.tabBarController?.selectedIndex = 0
129 | }
130 | }
131 | }
132 | else
133 | {
134 | print("certificate id == nil!") // shouldn't be possible
135 | }
136 |
137 | }
138 |
139 | actionController.addAction( okAction )
140 | self.present( actionController, animated: true, completion: nil )
141 | }
142 |
143 | func textFieldShouldReturn(_ textField: UITextField) -> Bool {
144 | topicTextField.resignFirstResponder()
145 | return true
146 | }
147 |
148 | func textFieldDidEndEditing(_ textField: UITextField) {
149 | topicTextField.text = textField.text
150 | let defaults = UserDefaults.standard
151 | let tabBarViewController = tabBarController as! IoTSampleTabBarController
152 | tabBarViewController.topic = textField.text!
153 | defaults.set(textField.text, forKey:"sliderTopic")
154 | }
155 |
156 | override func viewDidLoad() {
157 | super.viewDidLoad()
158 |
159 | topicTextField.delegate = self
160 | let defaults = UserDefaults.standard
161 | let certificateId = defaults.string( forKey: "certificateId")
162 | let sliderTopic = defaults.string( forKey: "sliderTopic" )
163 | let tabBarViewController = tabBarController as! IoTSampleTabBarController
164 |
165 | if (certificateId == nil)
166 | {
167 | deleteCertificateButton.isHidden=true
168 | }
169 | if (sliderTopic != nil)
170 | {
171 | tabBarViewController.topic=sliderTopic!
172 | }
173 |
174 | topicTextField.text = tabBarViewController.topic
175 | }
176 |
177 | override func viewWillAppear(_ animated: Bool) {
178 | super.viewWillAppear(animated)
179 |
180 | let defaults = UserDefaults.standard
181 | let certificateId = defaults.string( forKey: "certificateId")
182 |
183 | if (certificateId == nil)
184 | {
185 | deleteCertificateButton.isHidden=true
186 | }
187 | else
188 | {
189 | deleteCertificateButton.isHidden=false
190 | }
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/ConnectionViewController+Websocket.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 | import UIKit
16 | import AWSIoT
17 | import AWSMobileClient
18 |
19 | extension ConnectionViewController {
20 |
21 | func mqttEventCallbackWebsocket(_ status: AWSIoTMQTTStatus) {
22 | guard case .connected = status else {
23 | mqttEventCallback(status)
24 | return
25 | }
26 |
27 | DispatchQueue.main.async {
28 | let tabBarViewController = self.tabBarController as! IoTSampleTabBarController
29 | tabBarViewController.mqttStatus = "Connected"
30 | self.activityIndicatorView.stopAnimating()
31 | self.connected = true
32 | self.connectIoTDataWebSocket.setTitle("Disconnect \(self.IOT_WEBSOCKET)", for:UIControl.State())
33 | self.logTextView.text = "Connected via websocket"
34 | self.connectIoTDataWebSocket.isEnabled = true
35 | tabBarViewController.viewControllers = [ self, self.publishViewController, self.subscribeViewController ]
36 | }
37 | }
38 |
39 | @objc func didTapConnectIoTDataWebSocket(_ sender: UIButton) {
40 | sender.isEnabled = false
41 | if (connected == false) {
42 | handleConnectViaWebsocket()
43 | } else {
44 | handleDisconnect()
45 | DispatchQueue.main.async {
46 | sender.setTitle("Connect \(self.IOT_WEBSOCKET)", for:UIControl.State())
47 | sender.isEnabled = true
48 | }
49 | }
50 | }
51 |
52 | func handleConnectViaWebsocket() {
53 | self.connectButton.isHidden = true
54 | activityIndicatorView.startAnimating()
55 | DispatchQueue.main.async {
56 | self.logTextView.text = "Connecting (data plane)..."
57 | }
58 | let uuid = UUID().uuidString
59 | // Connect to the AWS IoT data plane service over websocket
60 | iotDataManager.connectUsingWebSocket(withClientId: uuid, cleanSession: true, statusCallback: mqttEventCallbackWebsocket(_:))
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Constants.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import Foundation
17 | import AWSCore
18 |
19 | //WARNING: To run this sample correctly, you must set the following constants.
20 |
21 | let CertificateSigningRequestCommonName = "IoTSampleSwift Application"
22 | let CertificateSigningRequestCountryName = "Your Country"
23 | let CertificateSigningRequestOrganizationName = "Your Organization"
24 | let CertificateSigningRequestOrganizationalUnitName = "Your Organizational Unit"
25 |
26 | let POLICY_NAME = "YourPolicyName"
27 |
28 | // This is the endpoint in your AWS IoT console. eg: https://xxxxxxxxxx.iot..amazonaws.com
29 | let AWS_REGION = AWSRegionType.Unknown
30 |
31 | //For both connecting over websockets and cert, IOT_ENDPOINT should look like
32 | //https://xxxxxxx-ats.iot.REGION.amazonaws.com
33 | let IOT_ENDPOINT = "https://xxxxxxxxxx.iot..amazonaws.com"
34 | let IDENTITY_POOL_ID = ":"
35 |
36 | //Used as keys to look up a reference of each manager
37 | let AWS_IOT_DATA_MANAGER_KEY = "MyIotDataManager"
38 | let AWS_IOT_MANAGER_KEY = "MyIotManager"
39 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UIStatusBarTintParameters
34 |
35 | UINavigationBar
36 |
37 | Style
38 | UIBarStyleDefault
39 | Translucent
40 |
41 |
42 |
43 | UISupportedInterfaceOrientations
44 |
45 | UIInterfaceOrientationPortrait
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 | UISupportedInterfaceOrientations~ipad
50 |
51 | UIInterfaceOrientationPortrait
52 | UIInterfaceOrientationPortraitUpsideDown
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/IoTSampleSwift.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)Amazon-Web-Services.IoTSampleSwift
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/IoTSampleTabBarController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 |
18 | class IoTSampleTabBarController: UITabBarController {
19 |
20 | @objc var mqttStatus: String = "Disconnected"
21 | @objc var topic: String = "slider"
22 | }
23 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/PublishViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSIoT
18 |
19 | class PublishViewController: UIViewController {
20 |
21 | @IBOutlet weak var publishSlider: UISlider!
22 |
23 | @IBAction func sliderValueChanged(_ sender: UISlider) {
24 | print("Publish slider value: " + "\(sender.value)")
25 |
26 | let iotDataManager = AWSIoTDataManager(forKey: AWS_IOT_DATA_MANAGER_KEY)
27 | let tabBarViewController = tabBarController as! IoTSampleTabBarController
28 |
29 | iotDataManager.publishString("\(sender.value)", onTopic:tabBarViewController.topic, qoS:.messageDeliveryAttemptedAtMostOnce)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/IoTSampleSwift/SubscribeViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSIoT
18 |
19 | class SubscribeViewController: UIViewController {
20 |
21 | @IBOutlet weak var subscribeSlider: UISlider!
22 |
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 |
26 | // Do any additional setup after loading the view, typically from a nib.
27 | subscribeSlider.isEnabled = false
28 | }
29 |
30 | override func viewWillAppear(_ animated: Bool) {
31 | let iotDataManager = AWSIoTDataManager(forKey: AWS_IOT_DATA_MANAGER_KEY)
32 | let tabBarViewController = tabBarController as! IoTSampleTabBarController
33 |
34 | iotDataManager.subscribe(toTopic: tabBarViewController.topic, qoS: .messageDeliveryAttemptedAtMostOnce, messageCallback: {
35 | (payload) ->Void in
36 | let stringValue = NSString(data: payload, encoding: String.Encoding.utf8.rawValue)!
37 |
38 | print("received: \(stringValue)")
39 | DispatchQueue.main.async {
40 | self.subscribeSlider.value = stringValue.floatValue
41 | }
42 | } )
43 | }
44 |
45 | override func viewWillDisappear(_ animated: Bool) {
46 | let iotDataManager = AWSIoTDataManager(forKey: AWS_IOT_DATA_MANAGER_KEY)
47 | let tabBarViewController = tabBarController as! IoTSampleTabBarController
48 | iotDataManager.unsubscribeTopic(tabBarViewController.topic)
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '12.0'
2 | use_frameworks!
3 |
4 | target 'IoTSampleSwift' do
5 | pod 'AWSMobileClient'
6 | pod 'AWSIoT'
7 | end
8 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/README.md:
--------------------------------------------------------------------------------
1 | # The Amazon IoT Sample
2 |
3 | This sample demonstrates use of the AWS IoT APIs to securely publish to and subscribe from an MQTT topic. It uses Cognito authentication in conjunction with AWS IoT to create an identity (client certificate and private key) and store it in the iOS keychain. This identity is then used to authenticate to AWS IoT. Once a connection to the AWS IoT platform has been established, the application can operate in either the publish or subscribe role; the data format is a single floating point number in the range of 1-50. A configuration tab is provided allowing the user to select the name of the MQTT topic being published to or subscribed from, or to delete the identity. This application also supports the use of a pre-existing identity.
4 |
5 | ## Requirements
6 |
7 | * Xcode 9.2 and later
8 | * iOS 9 and later
9 |
10 | ## Using the Sample
11 |
12 | 1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods:
13 |
14 | ```sh
15 | sudo gem install cocoapods
16 | pod setup
17 | ```
18 |
19 | 1. To install the AWS Mobile SDK for iOS, change the current directory to the one with your **Podfile** in it and run the following command:
20 |
21 | ```sh
22 | pod install
23 | ```
24 |
25 | 1. This sample requires Cognito to authorize to AWS IoT in order to create a device certificate. Use Amazon Cognito to create a new identity pool:
26 | 1. In the [Amazon Cognito Console](https://console.aws.amazon.com/cognito/), press the `Manage Federated Identities` button and on the resulting page press the `Create new identity pool` button.
27 | 1. Give your identity pool a name and ensure that `Enable access to unauthenticated identities` under the `Unauthenticated identities` section is checked. This allows the sample application to assume the unauthenticated role associated with this identity pool. Press the `Create Pool` button to create your identity pool.
28 |
29 | **Important**: see note below on unauthenticated user access.
30 |
31 | 1. As part of creating the identity pool, Cognito will setup two roles in [Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/home#roles). These will be named something similar to: `Cognito_PoolNameAuth_Role` and `Cognito_PoolNameUnauth_Role`. You can view them by pressing the `View Details` button. Now press the `Allow` button to create the roles.
32 | 1. Save the `Identity pool ID` value that shows up in red in the "Getting started with Amazon Cognito" page, it should look similar to: `us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" and note the region that is being used. These will be used in the application code later.
33 | 1. Now we will attach a policy to the unauthenticated role which has permissions to access the required AWS IoT APIs. This is done by first creating an IAM Policy in the [IAM Console](https://console.aws.amazon.com/iam/home#roles) and then attaching it to the unauthenticated role. Click into Roles and search using the name used for the roles created above. Click on the link for the unauth role. Click on the "Add inline policy" button and add the following example policy which can be used with the sample application. This policy allows the application to create a new certificate (including private key) as well as attach an existing policy to a certificate.
34 |
35 | ```json
36 | {
37 | "Version": "2012-10-17",
38 | "Statement": [
39 | {
40 | "Effect": "Allow",
41 | "Action": [
42 | "iot:AttachPrincipalPolicy",
43 | "iot:CreateKeysAndCertificate",
44 | "iot:CreateCertificateFromCsr"
45 | ],
46 | "Resource": [
47 | "*"
48 | ]
49 | }
50 | ]
51 | }
52 | ```
53 |
54 | More information on AWS IAM roles and policies can be found [here](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html). More information on AWS IoT policies can be found [here](http://docs.aws.amazon.com/iot/latest/developerguide/authorization.html).
55 |
56 | **Note**: to keep this example simple it makes use of unauthenticated users in the identity pool. This can be used for getting started and prototypes but unauthenticated users should typically only be given read-only permissions if used in production applications. More information on Cognito identity pools including the Cognito developer guide can be found [here](http://aws.amazon.com/cognito/).
57 |
58 | 1. Note that the application does not actually create the AWS IoT policy itself, rather it relies on a policy to already be created in AWS IoT and then makes a call to attach that policy to the newly created certificate. To create a policy in AWS IoT,
59 | 1. Navigate to the [AWS IoT Console](https://console.aws.amazon.com/iot/home) and press the `Get Started` button. On the resulting page click on `Secure` on the side panel and the click on `Policies`.
60 | 1. Click on `Create a Policy`
61 | 1. Give the policy a name. Note this name as this is the string you will use in the application when making the attach policy API call.
62 | 1. The policy should be created to allow connecting to AWS IoT as well as allowing publishing, subscribing and receiving messages on whatever topics you will use in the sample application. Below is an example policy. This policy allows access to all topics under your AWS IoT account. To scope this policy down to specific topics specify them explicitly as ARNs in the resource section: `"Resource": "arn:aws:iot:::topic/mytopic/mysubtopic"`. Note that the first `topic` is an ARN specifer so this example actually specifies the topic `mytopic/mysubtopic`.
63 | 1. To add this policy, click on `Advanced Mode` and replace the default policy with the following text and then click the `Create` button.
64 |
65 | ```json
66 | {
67 | "Version": "2012-10-17",
68 | "Statement": [
69 | {
70 | "Effect": "Allow",
71 | "Action": "iot:Connect",
72 | "Resource": "*"
73 | },
74 | {
75 | "Effect": "Allow",
76 | "Action": [
77 | "iot:Publish",
78 | "iot:Subscribe",
79 | "iot:Receive"
80 | ],
81 | "Resource": "*"
82 | }
83 | ]
84 | }
85 | ```
86 |
87 | 1. Open `IoTSampleSwift.xcworkspace`.
88 |
89 | 1. Open `awsconfiguration.json` and update the Cognito Identity Pool ID (from the value you saved above) and Cognito region for Cognito Identity Pool ID (for example us-east-1).
90 |
91 | ```json
92 | "CredentialsProvider": {
93 | "CognitoIdentity": {
94 | "Default": {
95 | "PoolId": "CHANGE_ME",
96 | "Region": "CHANGE_ME"
97 | }
98 | }
99 | }
100 | ```
101 |
102 | 1. Open `Constants.swift` and update the following lines with the appropriate constants:
103 |
104 | ```swift
105 | let CertificateSigningRequestCommonName = "IoTSampleSwift Application"
106 | let CertificateSigningRequestCountryName = "Your Country"
107 | let CertificateSigningRequestOrganizationName = "Your Organization"
108 | let CertificateSigningRequestOrganizationalUnitName = "Your Organizational Unit"
109 | let PolicyName = "YourPolicyName"
110 |
111 | let AwsRegion = AWSRegionType.Unknown
112 | let IOT_ENDPOINT = "https://xxxxxxxxxx.iot..amazonaws.com" // make sure to include "https://" prefix
113 | ```
114 |
115 | Note: The endpoint can be found under [IoT Home](https://console.aws.amazon.com/iot/home). Once there, scroll down and click Settings on the side navigation on the left side. For Certificate details, navigate to ***Secure > Certificates*** and select the specific certificate to view certificate details such as CommonName (CN), OrganizationName (O), OrganizationUnit(OU), and Country (C).
116 |
117 | 1. Add the IoT certificate (IoT identity) to the Xcode project
118 | 1. Follow the instructions below to create the certificate
119 | 1. Place the PKCS #12 archive (.p12) in the same directory as Info.plist
120 | 1. Add it to the same group in Xcode as Info.plist
121 | 1. Select the build targets which will use this IoT identity
122 |
123 | 1. Build and run the sample app on two different simulators or devices. After you connect then changes in one devices publish panel will show up in the other devices subscribe panel.
124 |
125 | The sample application will allow you to connect to the AWS IoT platform, and then publish or subscribe to a topic using MQTT. You can configure the topic name under the 'Configuration' tab; it's set to 'slider' by default (only when you are disconnected). You can use another instance of this application so that one instance publishes while the other subscribes, or you can use the MQTT client in the [Amazon AWS IoT console](https://console.aws.amazon.com/iot/) to interact with your application.
126 |
127 | ## Prepare IoT Certificate for Identity
128 |
129 | You can also configure the sample application to use an existing AWS IoT identity. To do this, create a certificate and private key in the [Amazon AWS IoT console](https://console.aws.amazon.com/iot/) and associate it with a policy which allows access to 'iot:\*'. Go to the section named Secure and click on Certificates on the side navigation on the left sideN. Download the generated files and use the following command to create a PKCS #12 archive from the certificate and private key (NOTE: the filename must use the .p12 suffix):
130 |
131 | ```sh
132 | openssl pkcs12 -export -in certificate.pem.crt -inkey private.pem.key -out awsiot-identity.p12
133 | ```
134 |
135 | When prompted for `Enter Export Password:`, enter the default empty string as the export password.
136 |
137 | The app will use this IoT identity instead of creating one dynamically. Note that when using your own certificate and private key, the "Delete" option under the "Configuration" tab only deletes them from the keychain; they remain in the application itself and will be re-added into the keychain the next time you connect.
138 |
--------------------------------------------------------------------------------
/IoT-Sample/Swift/awsconfiguration.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "1.0",
3 | "IdentityManager": {
4 | "Default": {}
5 | },
6 | "CredentialsProvider": {
7 | "CognitoIdentity": {
8 | "Default": {
9 | "PoolId": "CHANGE_ME",
10 | "Region": "CHANGE_ME"
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 |
4 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5 |
6 | 1. Definitions.
7 |
8 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
9 |
10 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
11 |
12 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
13 |
14 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
15 |
16 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
17 |
18 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
19 |
20 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
21 |
22 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
23 |
24 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
25 |
26 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
27 |
28 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
29 |
30 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
31 |
32 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
33 |
34 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
35 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and
36 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
37 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
38 |
39 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
40 |
41 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
42 |
43 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
44 |
45 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
46 |
47 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
48 |
49 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
50 |
51 | END OF TERMS AND CONDITIONS
52 |
53 | =============================
54 |
55 | ELCImagePickerController
56 |
57 | The MIT License
58 |
59 | Copyright (c) 2010 ELC Technologies
60 |
61 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
62 |
63 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
64 |
65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66 |
67 | =============================
68 |
69 | JTSImageViewController
70 |
71 | The MIT License (MIT)
72 |
73 | Copyright (c) 2014 Jared Sinclair
74 |
75 | Permission is hereby granted, free of charge, to any person obtaining a copy
76 | of this software and associated documentation files (the "Software"), to deal
77 | in the Software without restriction, including without limitation the rights
78 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79 | copies of the Software, and to permit persons to whom the Software is
80 | furnished to do so, subject to the following conditions:
81 |
82 | The above copyright notice and this permission notice shall be included in all
83 | copies or substantial portions of the Software.
84 |
85 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
86 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
87 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
88 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
89 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
90 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
91 | SOFTWARE.
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import
17 |
18 | @interface AppDelegate : UIResponder
19 |
20 | @property (strong, nonatomic) UIWindow *window;
21 |
22 | @end
23 |
24 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import "AppDelegate.h"
17 | #import "Constants.h"
18 | #import
19 | #import
20 |
21 | static NSString *AWSLexVoiceButtonIdentifierKey = @"AWSLexVoiceButton";
22 | static NSString *AWSLexChatConfigIdentifierKey = @"chatConfig";
23 |
24 | @interface AppDelegate ()
25 |
26 | @end
27 |
28 | @implementation AppDelegate
29 |
30 |
31 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
32 | AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]
33 | initWithRegionType:CognitoRegionType
34 | identityPoolId:CognitoIdentityPoolId];
35 |
36 | AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:LexRegionType credentialsProvider:credentialsProvider];
37 |
38 | [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
39 |
40 | AWSLexInteractionKitConfig *config = [AWSLexInteractionKitConfig defaultInteractionKitConfigWithBotName:BotName botAlias:BotAlias];
41 |
42 | [AWSLexInteractionKit registerInteractionKitWithServiceConfiguration:configuration interactionKitConfiguration:config forKey:AWSLexVoiceButtonIdentifierKey];
43 |
44 | AWSLexInteractionKitConfig *chatConfig = [AWSLexInteractionKitConfig defaultInteractionKitConfigWithBotName:BotName botAlias:BotAlias];
45 | chatConfig.autoPlayback = NO;
46 | [AWSLexInteractionKit registerInteractionKitWithServiceConfiguration:configuration interactionKitConfiguration:chatConfig forKey:AWSLexChatConfigIdentifierKey];
47 |
48 | return YES;
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
101 |
102 |
103 |
104 |
105 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/ChatViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import
17 | #import
18 |
19 | @interface ChatViewController : JSQMessagesViewController
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/ChatViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import "ChatViewController.h"
17 | #import
18 | #import
19 |
20 | #define HEIGHT 100;
21 | #define CLIENT_SENDER_ID @"client"
22 | #define SERVER_SENDER_ID @"server"
23 | #define CONFIG_KEY @"chatConfig"
24 |
25 | @interface ChatViewController()
26 |
27 | @property (nonatomic, strong) NSMutableArray *messages;
28 |
29 | @property (nonatomic, strong) AWSLexInteractionKit *interactionKit;
30 |
31 | @property (nonatomic, strong) NSDictionary *sessionAttributes;
32 |
33 | @property (strong, nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageData;
34 |
35 | @property (strong, nonatomic) JSQMessagesBubbleImage *incomingBubbleImageData;
36 |
37 | @end
38 |
39 | @implementation ChatViewController{
40 | JSQMessage *speechMessage;
41 | NSUInteger speechIndex;
42 | AWSTaskCompletionSource *textModeSwitchingCompletion;
43 | NSUInteger count;
44 | }
45 |
46 | -(void)viewDidLoad{
47 | [super viewDidLoad];
48 | count = 0;
49 | self.interactionKit = [AWSLexInteractionKit interactionKitForKey:CONFIG_KEY];
50 | self.interactionKit.interactionDelegate = self;
51 | self.interactionKit.microphoneDelegate = self;
52 |
53 | self.showLoadEarlierMessagesHeader = NO;
54 | self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
55 | self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
56 | self.inputToolbar.contentView.textView.keyboardType = UIKeyboardTypeDefault;
57 | self.messages = [NSMutableArray new];
58 |
59 | JSQMessagesBubbleImageFactory *bubbleFactory = [[JSQMessagesBubbleImageFactory alloc] init];
60 |
61 | self.outgoingBubbleImageData = [bubbleFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
62 | self.incomingBubbleImageData = [bubbleFactory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleGreenColor]];
63 | self.inputToolbar.contentView.leftBarButtonItem = nil;
64 | }
65 |
66 | - (void)didPressSendButton:(UIButton *)button
67 | withMessageText:(NSString *)text
68 | senderId:(NSString *)senderId
69 | senderDisplayName:(NSString *)senderDisplayName
70 | date:(NSDate *)date
71 | {
72 | JSQMessage *message = [[JSQMessage alloc] initWithSenderId:senderId
73 | senderDisplayName:senderDisplayName
74 | date:date
75 | text:text];
76 |
77 | [self.messages addObject:message];
78 |
79 | if(textModeSwitchingCompletion){
80 | [textModeSwitchingCompletion setResult:text];
81 | textModeSwitchingCompletion = nil;
82 | }else{
83 | [self.interactionKit textInTextOut:text];
84 | }
85 | [self finishSendingMessageAnimated:YES];
86 | }
87 |
88 | - (NSString *)senderDisplayName
89 | {
90 | return @"Sender";
91 | }
92 |
93 | - (NSString *)senderId
94 | {
95 | return CLIENT_SENDER_ID;
96 | }
97 |
98 | - (id)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath
99 | {
100 | return [self.messages objectAtIndex:indexPath.item];
101 | }
102 |
103 | - (void)collectionView:(JSQMessagesCollectionView *)collectionView didDeleteMessageAtIndexPath:(NSIndexPath *)indexPath
104 | {
105 | // Do nothing
106 | }
107 |
108 | - (id)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
109 | {
110 |
111 | JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
112 |
113 | if ([message.senderId isEqualToString:self.senderId]) {
114 | return self.outgoingBubbleImageData;
115 | }
116 |
117 | return self.incomingBubbleImageData;
118 | }
119 |
120 | - (id)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
121 | {
122 | return nil;
123 | }
124 |
125 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
126 | {
127 | return [self.messages count];
128 | }
129 |
130 | - (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
131 | {
132 | JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath];
133 |
134 | JSQMessage *msg = [self.messages objectAtIndex:indexPath.item];
135 |
136 | if (!msg.isMediaMessage) {
137 |
138 | if ([msg.senderId isEqualToString:self.senderId]) {
139 | cell.textView.textColor = [UIColor blackColor];
140 | }else {
141 | cell.textView.textColor = [UIColor whiteColor];
142 | }
143 |
144 | cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor,
145 | NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) };
146 | }
147 |
148 | return cell;
149 | }
150 |
151 |
152 | - (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
153 | {
154 | JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
155 | return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date];
156 | }
157 |
158 | - (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
159 | {
160 | JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
161 |
162 | // iOS7-style sender name labels
163 |
164 | if ([message.senderId isEqualToString:self.senderId]) {
165 | return nil;
166 | }
167 |
168 | if (indexPath.item - 1 > 0) {
169 | JSQMessage *previousMessage = [self.messages objectAtIndex:indexPath.item - 1];
170 | if ([[previousMessage senderId] isEqualToString:message.senderId]) {
171 | return nil;
172 | }
173 | }
174 |
175 | // Don't specify attributes to use the defaults.
176 | return [[NSAttributedString alloc] initWithString:message.senderDisplayName];
177 | }
178 |
179 | - (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
180 | {
181 | return nil;
182 | }
183 |
184 | - (BOOL)composerTextView:(JSQMessagesComposerTextView *)textView shouldPasteWithSender:(id)sender
185 | {
186 | return YES;
187 | }
188 |
189 | - (void)messageView:(JSQMessagesCollectionView *)view didTapAccessoryButtonAtIndexPath:(NSIndexPath *)path
190 | {
191 | NSLog(@"Tapped accessory button!");
192 | }
193 |
194 | #pragma mark InteractionKit
195 |
196 | - (void)interactionKit:(AWSLexInteractionKit *)interactionKit
197 | onError:(NSError *)error{
198 | // Do nothing for now.
199 | NSLog(@"error occured %@", error);
200 | }
201 |
202 | - (void)interactionKit:(AWSLexInteractionKit *)interactionKit
203 | switchModeInput:(AWSLexSwitchModeInput *)switchModeInput
204 | completionSource:(AWSTaskCompletionSource *)completionSource{
205 |
206 | self.sessionAttributes = switchModeInput.sessionAttributes;
207 |
208 | dispatch_async(dispatch_get_main_queue(), ^{
209 | JSQMessage *message = nil;
210 |
211 | if (switchModeInput.outputText != nil) {
212 | message = [[JSQMessage alloc] initWithSenderId:SERVER_SENDER_ID
213 | senderDisplayName:@""
214 | date:[[NSDate alloc]init]
215 | text:switchModeInput.outputText];
216 |
217 | [self.messages addObject:message];
218 | }
219 |
220 | [self finishSendingMessageAnimated:YES];
221 | });
222 |
223 | // This can expand to take input from user.
224 | AWSLexSwitchModeResponse *switchModeResponse = [AWSLexSwitchModeResponse new];
225 | [switchModeResponse setInteractionMode:AWSLexInteractionModeText];
226 | [switchModeResponse setSessionAttributes:switchModeInput.sessionAttributes];
227 | [completionSource setResult:switchModeResponse];
228 |
229 | }
230 |
231 | /*
232 | * Sent to delegate when the Switch mode requires a user to input a text. You should set the completion source result to the string that you get from the user. This ensures that the session attribute information is carried over from the previous request to the next one.
233 | */
234 | - (void)interactionKitContinueWithText:(AWSLexInteractionKit *)interactionKit
235 | completionSource:(AWSTaskCompletionSource *)completionSource{
236 | textModeSwitchingCompletion = completionSource;
237 | }
238 | #pragma mark -
239 |
240 | @end
241 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/Constants.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import
17 | #import
18 |
19 | FOUNDATION_EXPORT AWSRegionType const CognitoRegionType;
20 | FOUNDATION_EXPORT AWSRegionType const LexRegionType;
21 | FOUNDATION_EXPORT NSString *const CognitoIdentityPoolId;
22 | FOUNDATION_EXPORT NSString *const BotName;
23 | FOUNDATION_EXPORT NSString *const BotAlias;
24 |
25 | @interface Constants : NSObject
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/Constants.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import "Constants.h"
17 |
18 | #warning To run this sample correctly, you must set the following constants.
19 |
20 | AWSRegionType const CognitoRegionType = AWSRegionUnknown; // e.g. AWSRegionUSEast1
21 | AWSRegionType const LexRegionType = AWSRegionUnknown;
22 | NSString *const CognitoIdentityPoolId = @"YourCognitoIdentityPoolId";
23 | NSString *const BotName = @"YourBotName";
24 | NSString *const BotAlias = @"$LATEST";
25 |
26 | @implementation Constants
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSMicrophoneUsageDescription
26 | For recording Audio and transmitting it to service
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/TableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import
17 |
18 | @interface TableViewController : UITableViewController
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/TableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import "TableViewController.h"
17 |
18 | @interface TableViewController ()
19 |
20 | @property (nonatomic, strong) NSArray *conversationTypes;
21 |
22 |
23 | @end
24 |
25 | @implementation TableViewController
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 |
30 | self.conversationTypes = [[NSArray alloc]initWithObjects:@"Voice", @"Chat", nil];
31 |
32 | }
33 |
34 | - (void)didReceiveMemoryWarning {
35 | [super didReceiveMemoryWarning];
36 |
37 | }
38 |
39 | #pragma mark - Table view data source
40 |
41 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
42 | return 1;
43 | }
44 |
45 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
46 | return [self.conversationTypes count];
47 | }
48 |
49 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
50 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
51 | if(!cell){
52 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"reuseIdentifier"];
53 | }
54 |
55 | cell.textLabel.text = [self.conversationTypes objectAtIndex:indexPath.row];
56 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
57 |
58 | return cell;
59 | }
60 |
61 | - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
62 | if(indexPath.row == 0){
63 | [self performSegueWithIdentifier:@"voicecontroller" sender:self];
64 | }else{
65 | [self performSegueWithIdentifier:@"chatcontroller" sender:self];
66 | }
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import
17 | #import
18 |
19 | @interface ViewController : UIViewController
20 |
21 | @property (weak, nonatomic) IBOutlet AWSLexVoiceButton *voiceButton;
22 | @property (weak, nonatomic) IBOutlet UILabel *output;
23 | @property (weak, nonatomic) IBOutlet UILabel *input;
24 |
25 |
26 | @property (nonatomic, weak) id delegate;
27 | @end
28 |
29 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import "ViewController.h"
17 |
18 | @interface ViewController ()
19 |
20 | @end
21 |
22 | @implementation ViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | self.voiceButton.delegate = self;
27 | // Do any additional setup after loading the view, typically from a nib.
28 | }
29 |
30 | #pragma mark - VoiceButtonDelegate Methods
31 |
32 | - (void)voiceButton:(AWSLexVoiceButton *)button onResponse:(nonnull AWSLexVoiceButtonResponse *)response{
33 | // `inputTranscript` is the transcript of the voice input to the operation
34 | NSLog(@"Input Transcript: %@", response.inputTranscript);
35 | self.input.text = [NSString stringWithFormat:@"\"%@\"", response.inputTranscript];
36 |
37 | NSLog(@"on text output %@", response.outputText);
38 | self.output.text = response.outputText;
39 | }
40 |
41 | - (void)voiceButton:(AWSLexVoiceButton *)button onError:(NSError *)error{
42 | NSLog(@"error %@", error);
43 | }
44 |
45 | #pragma mark -
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Lex-Sample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | #import
17 | #import "AppDelegate.h"
18 |
19 | int main(int argc, char * argv[]) {
20 | @autoreleasepool {
21 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Lex-Sample/ObjC/Podfile:
--------------------------------------------------------------------------------
1 | ENV['SWIFT_VERSION'] = '5'
2 | platform :ios, '12.0'
3 | use_frameworks!
4 | target :'Lex-Sample' do
5 | pod 'JSQMessagesViewController', '~>7.3.4'
6 | pod 'AWSLex'
7 | end
8 |
9 | post_install do |installer|
10 | installer.pods_project.targets.each do |target|
11 | target.build_configurations.each do |config|
12 | config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
13 | end
14 | end
15 | end
--------------------------------------------------------------------------------
/Lex-Sample/Swift/.gitignore:
--------------------------------------------------------------------------------
1 | *.xcworkspace/
2 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | import UIKit
17 | import AWSCore
18 | import AWSLex
19 | import AWSMobileClient
20 |
21 | @UIApplicationMain
22 | class AppDelegate: UIResponder, UIApplicationDelegate {
23 |
24 | var window: UIWindow?
25 |
26 |
27 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
28 |
29 |
30 | AWSMobileClient.sharedInstance().initialize { (userState, error) in
31 | guard error == nil else {
32 | print("Error initializing AWSMobileClient. Error: \(error!.localizedDescription)")
33 | return
34 | }
35 | print("AWSMobileClient initialized.")
36 | }
37 |
38 | let configuration = AWSServiceConfiguration(region: LexRegion, credentialsProvider: AWSMobileClient.sharedInstance())
39 | AWSServiceManager.default().defaultServiceConfiguration = configuration
40 |
41 | let chatConfig = AWSLexInteractionKitConfig.defaultInteractionKitConfig(withBotName: BotName, botAlias: BotAlias)
42 | AWSLexInteractionKit.register(with: configuration!, interactionKitConfiguration: chatConfig, forKey: "AWSLexVoiceButton")
43 | chatConfig.autoPlayback = false
44 | AWSLexInteractionKit.register(with: configuration!, interactionKitConfiguration: chatConfig, forKey: "chatConfig")
45 |
46 | // Override point for customization after application launch.
47 | return true
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/ChatViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | import Foundation
17 | import JSQMessagesViewController
18 | import AWSLex
19 |
20 | let ClientSenderId = "Client"
21 | let ServerSenderId = "Server"
22 |
23 | class ChatViewController: JSQMessagesViewController, JSQMessagesComposerTextViewPasteDelegate {
24 |
25 | @objc var messages: [JSQMessage]?
26 | @objc var interactionKit: AWSLexInteractionKit?
27 | @objc var sessionAttributes: [AnyHashable: Any]?
28 | @objc var outgoingBubbleImageData: JSQMessagesBubbleImage?
29 | @objc var incomingBubbleImageData: JSQMessagesBubbleImage?
30 |
31 | @objc var speechMessage: JSQMessage?
32 | @objc var speechIndex: Int = 0
33 | @objc var textModeSwitchingCompletion: AWSTaskCompletionSource?
34 | var count: Int?
35 |
36 | override func viewDidLoad() {
37 | super.viewDidLoad()
38 | count = 0
39 | self.interactionKit = AWSLexInteractionKit.init(forKey: "chatConfig")
40 | self.interactionKit?.interactionDelegate = self
41 |
42 | self.showLoadEarlierMessagesHeader = false
43 | self.collectionView?.collectionViewLayout.incomingAvatarViewSize = CGSize.zero
44 | self.collectionView?.collectionViewLayout.outgoingAvatarViewSize = CGSize.zero
45 |
46 | self.inputToolbar.contentView?.textView?.keyboardType = UIKeyboardType.default
47 | self.messages = [JSQMessage]()
48 |
49 | let bubbleFactory = JSQMessagesBubbleImageFactory()
50 | self.outgoingBubbleImageData = bubbleFactory?.outgoingMessagesBubbleImage(with: UIColor.jsq_messageBubbleLightGray())
51 | self.incomingBubbleImageData = bubbleFactory?.incomingMessagesBubbleImage(with: UIColor.jsq_messageBubbleGreen())
52 |
53 | self.inputToolbar.contentView?.leftBarButtonItem = nil;
54 |
55 | }
56 |
57 | override func didPressSend(_ button: UIButton, withMessageText text: String, senderId: String, senderDisplayName: String, date: Date) {
58 | let message = JSQMessage(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
59 | self.messages?.append(message!)
60 |
61 | if let textModeSwitchingCompletion = textModeSwitchingCompletion {
62 | textModeSwitchingCompletion.set(result: text as NSString)
63 | self.textModeSwitchingCompletion = nil
64 | }
65 | else {
66 | self.interactionKit?.text(inTextOut: text)
67 | }
68 | self.finishSendingMessage(animated: true)
69 | }
70 |
71 | override var senderDisplayName:String! {
72 | get{
73 | return "John Doe"
74 | }
75 | set{
76 | //do nothing
77 | }
78 | }
79 |
80 | override var senderId:String! {
81 | get{
82 | return ClientSenderId
83 | }
84 | set{
85 | //do nothing
86 | }
87 | }
88 |
89 | override func collectionView(_ collectionView: JSQMessagesCollectionView, messageDataForItemAt indexPath: IndexPath) -> JSQMessageData {
90 |
91 | return self.messages![indexPath.item]
92 | }
93 |
94 | override func collectionView(_ collectionView: JSQMessagesCollectionView, didDeleteMessageAt indexPath: IndexPath) {
95 | //DO NOTHING
96 | }
97 |
98 | override func collectionView(_ collectionView: JSQMessagesCollectionView, messageBubbleImageDataForItemAt indexPath: IndexPath) -> JSQMessageBubbleImageDataSource {
99 | let message = self.messages![indexPath.item]
100 | if (message.senderId == self.senderId) {
101 | return self.outgoingBubbleImageData!
102 | }
103 | return self.incomingBubbleImageData!
104 | }
105 |
106 | override func collectionView(_ collectionView: JSQMessagesCollectionView, avatarImageDataForItemAt indexPath: IndexPath) -> JSQMessageAvatarImageDataSource? {
107 | return nil
108 | }
109 |
110 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
111 | if let messages = messages {
112 | return messages.count
113 | }
114 | return 0
115 | }
116 |
117 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
118 |
119 | let cell = (super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell)
120 | let msg = self.messages?[indexPath.item]
121 | if !msg!.isMediaMessage {
122 | if (msg?.senderId == self.senderId) {
123 | cell.textView?.textColor = UIColor.black
124 | }
125 | else {
126 | cell.textView?.textColor = UIColor.white
127 | }
128 | }
129 | return cell
130 | }
131 |
132 | override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForCellTopLabelAt indexPath: IndexPath) -> NSAttributedString? {
133 | if indexPath.item % 3 == 0 {
134 | let message = self.messages?[indexPath.item]
135 | return JSQMessagesTimestampFormatter.shared().attributedTimestamp(for: message!.date)
136 | }
137 | return nil
138 | }
139 |
140 | override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForMessageBubbleTopLabelAt indexPath: IndexPath) -> NSAttributedString? {
141 | let message = self.messages?[indexPath.item]
142 | /**
143 | * iOS7-style sender name labels
144 | */
145 | if (message?.senderId == self.senderId) {
146 | return nil
147 | }
148 | if indexPath.item - 1 > 0 {
149 | let previousMessage = self.messages?[indexPath.item - 1]
150 | if (previousMessage?.senderId == message?.senderId) {
151 | return nil
152 | }
153 | }
154 | /**
155 | * Don't specify attributes to use the defaults.
156 | */
157 | return NSAttributedString(string: message!.senderDisplayName)
158 | }
159 |
160 | override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForCellBottomLabelAt indexPath: IndexPath) -> NSAttributedString? {
161 | return nil
162 | }
163 |
164 | public func composerTextView(_ textView: JSQMessagesComposerTextView, shouldPasteWithSender sender: Any) -> Bool {
165 | return true
166 | }
167 |
168 | }
169 |
170 | // MARK: Interaction Kit
171 | extension ChatViewController: AWSLexInteractionDelegate {
172 |
173 | @objc public func interactionKitOnRecordingEnd(_ interactionKit: AWSLexInteractionKit, audioStream: Data, contentType: String) {
174 | DispatchQueue.main.async(execute: {
175 | let audioItem = JSQAudioMediaItem(data: audioStream)
176 | self.speechMessage = JSQMessage(senderId: ClientSenderId, displayName: "", media: audioItem)
177 |
178 | self.messages?[self.speechIndex] = self.speechMessage!
179 | self.finishSendingMessage(animated: true)
180 | })
181 | }
182 |
183 | public func interactionKit(_ interactionKit: AWSLexInteractionKit, onError error: Error) {
184 | //do nothing for now.
185 | }
186 |
187 | public func interactionKit(_ interactionKit: AWSLexInteractionKit, switchModeInput: AWSLexSwitchModeInput, completionSource: AWSTaskCompletionSource?) {
188 | self.sessionAttributes = switchModeInput.sessionAttributes
189 | DispatchQueue.main.async(execute: {
190 | let message: JSQMessage
191 | // Handle a successful fulfillment
192 | if (switchModeInput.dialogState == AWSLexDialogState.readyForFulfillment) {
193 | // Currently just displaying the slots returned on ready for fulfillment
194 | if let slots = switchModeInput.slots {
195 | message = JSQMessage(senderId: ServerSenderId, senderDisplayName: "", date: Date(), text: "Slots:\n\(slots)")
196 | self.messages?.append(message)
197 | self.finishSendingMessage(animated: true)
198 | }
199 | } else {
200 | //if you have special characters you need to be returned, make sure you base 64 encode your responses in your bot and then they will be decoded here as needed.
201 | guard let text = switchModeInput.outputText else {
202 | return //no response was returned
203 | }
204 | if let base64DecodedText = text.base64Decoded {
205 | message = JSQMessage(senderId: ServerSenderId, senderDisplayName: "", date: Date(), text: base64DecodedText)
206 | } else {
207 | message = JSQMessage(senderId: ServerSenderId, senderDisplayName: "", date: Date(), text: text)
208 | }
209 |
210 | self.messages?.append(message)
211 | self.finishSendingMessage(animated: true)
212 | }
213 | })
214 | //this can expand to take input from user.
215 | let switchModeResponse = AWSLexSwitchModeResponse()
216 | switchModeResponse.interactionMode = AWSLexInteractionMode.text
217 | switchModeResponse.sessionAttributes = switchModeInput.sessionAttributes
218 | completionSource?.set(result: switchModeResponse)
219 | }
220 |
221 | /*
222 | * Sent to delegate when the Switch mode requires a user to input a text. You should set the completion source result to the string that you get from the user. This ensures that the session attribute information is carried over from the previous request to the next one.
223 | */
224 | func interactionKitContinue(withText interactionKit: AWSLexInteractionKit, completionSource: AWSTaskCompletionSource) {
225 | textModeSwitchingCompletion = completionSource
226 | }
227 |
228 | }
229 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | import Foundation
17 | import AWSCore
18 |
19 | // WARNING: To run this sample correctly, you must set the following constants.
20 |
21 | let LexRegion = AWSRegionType.Unknown // Change this is this is not your Lex region (most are currently AWSRegionType.USEast1)
22 | let BotName = "BotName" // Put your bot name here
23 | let BotAlias = "$LATEST" // You can leave this if you always want to use
24 | // the latest version of your bot or put the version
25 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSMicrophoneUsageDescription
6 | For recording Audio and transmitting it to service
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Lex Sample
11 | CFBundleExecutable
12 | $(EXECUTABLE_NAME)
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | $(PRODUCT_NAME)
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1
27 | LSRequiresIPhoneOS
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UISupportedInterfaceOrientations
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationLandscapeLeft
41 | UIInterfaceOrientationLandscapeRight
42 |
43 | UISupportedInterfaceOrientations~ipad
44 |
45 | UIInterfaceOrientationPortrait
46 | UIInterfaceOrientationPortraitUpsideDown
47 | UIInterfaceOrientationLandscapeLeft
48 | UIInterfaceOrientationLandscapeRight
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
101 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/StringExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StringExtension.swift
3 | // LexSwift
4 | //
5 | // Created by Stone, Nicki on 4/10/20.
6 | //
7 |
8 | import Foundation
9 |
10 | public extension String {
11 |
12 | /// Assuming the current string is base64 encoded, this property returns a String
13 | /// initialized by converting the current string into Unicode characters, encoded to
14 | /// utf8. If the current string is not base64 encoded, nil is returned instead.
15 | var base64Decoded: String? {
16 | guard let base64 = Data(base64Encoded: self) else { return nil }
17 | let utf8 = String(data: base64, encoding: .utf8)
18 | return utf8
19 | }
20 |
21 | /// Returns a base64 representation of the current string, or nil if the
22 | /// operation fails.
23 | var base64Encoded: String? {
24 | let utf8 = self.data(using: .utf8)
25 | let base64 = utf8?.base64EncodedString()
26 | return base64
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/TableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | import Foundation
17 | import UIKit
18 |
19 | class TableViewController: UITableViewController {
20 |
21 | @objc var conversationTypes: [String]?
22 |
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 | self.conversationTypes = ["Voice", "Chat"]
26 | }
27 |
28 | override func numberOfSections(in tableView: UITableView) -> Int {
29 | return 1
30 | }
31 |
32 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
33 | return self.conversationTypes!.count
34 | }
35 |
36 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
37 | let cell = UITableViewCell(style: .default, reuseIdentifier: "reuseIdentifier")
38 | cell.textLabel?.text = self.conversationTypes![indexPath.row]
39 | cell.accessoryType = .disclosureIndicator
40 | return cell
41 | }
42 |
43 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
44 | if indexPath.row == 0 {
45 | self.performSegue(withIdentifier: "voicecontroller", sender: self)
46 | }
47 | else {
48 | self.performSegue(withIdentifier: "chatcontroller", sender: self)
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/LexSwift/VoiceChatViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License").
5 | // You may not use this file except in compliance with the License.
6 | // A copy of the License is located at
7 | //
8 | // http://aws.amazon.com/apache2.0
9 | //
10 | // or in the "license" file accompanying this file. This file is distributed
11 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | // express or implied. See the License for the specific language governing
13 | // permissions and limitations under the License.
14 | //
15 |
16 | import Foundation
17 | import AWSLex
18 | import UIKit
19 |
20 |
21 | class VoiceChatViewController: UIViewController, AWSLexVoiceButtonDelegate {
22 |
23 | @IBOutlet weak var voiceButton: AWSLexVoiceButton!
24 | @IBOutlet weak var input: UILabel!
25 | @IBOutlet weak var output: UILabel!
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 | (self.voiceButton as AWSLexVoiceButton).delegate = self
30 | }
31 |
32 | func voiceButton(_ button: AWSLexVoiceButton, on response: AWSLexVoiceButtonResponse) {
33 | DispatchQueue.main.async(execute: {
34 | // `inputTranscript` is the transcript of the voice input to the operation
35 | if let inputTranscript = response.inputTranscript {
36 | print("Input Transcript: " + inputTranscript)
37 | self.input.text = "\"\(inputTranscript)\""
38 | }
39 |
40 | if let outputText = response.outputText {
41 | print("Output Transcript: " + outputText)
42 | self.output.text = outputText
43 | } else {
44 | self.output.text = ""
45 | }
46 | })
47 | }
48 |
49 | public func voiceButton(_ button: AWSLexVoiceButton, onError error: Error) {
50 | print("error \(error)")
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '12.0'
2 | use_frameworks!
3 | target :'LexSwift' do
4 | pod 'JSQMessagesViewController', '~>7.3.4'
5 |
6 | pod 'AWSMobileClient'
7 | pod 'AWSLex'
8 | end
9 |
10 | post_install do |installer|
11 | installer.pods_project.targets.each do |target|
12 | target.build_configurations.each do |config|
13 | config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
14 | end
15 | end
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/README.md:
--------------------------------------------------------------------------------
1 | # The Amazon Lex Sample
2 |
3 | This sample demonstrates how to use Amazon Lex interaction client library on iOS. This application uses AWS Cognito for authentication with Amazon Lex.
4 |
5 | ## Requirements
6 |
7 | * Xcode 9.2 and later
8 | * iOS 9 and later
9 |
10 | ## Using the Sample
11 |
12 | 1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods:
13 |
14 | sudo gem install cocoapods
15 | pod setup
16 |
17 | 1. To install the AWS Mobile SDK for iOS, change the current directory to the one with your **Podfile** in it and run the following command:
18 |
19 | pod install
20 |
21 | 1. This sample requires Cognito to authorize to Amazon Lex to post content. Use Amazon Cognito to create a new identity pool:
22 | 1. In the [Amazon Cognito Console](https://console.aws.amazon.com/cognito/), press the `Manage Federated Identities` button and on the resulting page press the `Create new identity pool` button.
23 | 1. Give your identity pool a name and ensure that `Enable access to unauthenticated identities` under the `Unauthenticated identities` section is checked. This allows the sample application to assume the unauthenticated role associated with this identity pool. Press the `Create Pool` button to create your identity pool.
24 |
25 | **Important**: see note below on unauthenticated user access.
26 |
27 | 1. As part of creating the identity pool, Cognito will setup two roles in [Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/home#roles). These will be named something similar to: `Cognito_PoolNameAuth_Role` and `Cognito_PoolNameUnauth_Role`. You can view them by pressing the `View Details` button. Now press the `Allow` button to create the roles.
28 | 1. Save the `Identity pool ID` value that shows up in red in the "Getting started with Amazon Cognito" page, it should look similar to: `us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` and note the region that is being used. These will be used in the application code later.
29 | 1. Now we will attach a policy to the unauthenticated role which has permissions to access the required Amazon Lex API. This is done by attaching an IAM Policy to the unauthenticated role in the [IAM Console](https://console.aws.amazon.com/iam/home#roles). First, search for the unauth role that you created in step 3 above (named something similar to `Cognito_PoolNameUnauth_Role`) and select its hyperlink. In the resulting "Summary" page press the `Attach Policy` button in the "Permissions" tab.
30 | 1. Search for "lex" and check the box next to the policy named `AmazonLexRunBotsOnly` and then press the `Attach Policy` button. This policy allows the application access to Amazon Lex conversational APIs.
31 |
32 | More information on AWS IAM roles and policies can be found [here](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html). More information on Amazon Lex policies can be found [here](http://docs.aws.amazon.com/lex/latest/dg/access-control-managing-permissions.html).
33 |
34 | **Note**: to keep this example simple it makes use of unauthenticated users in the identity pool. This can be used for getting started and prototypes but unauthenticated users should typically only be given read-only permissions in production applications. More information on Cognito identity pools including the Cognito developer guide can be found [here](http://aws.amazon.com/cognito/).
35 | 1. Use the [Amazon Lex console](https://console.aws.amazon.com/lex/home) to configure a bot that interacts with your mobile app features. To learn more, see [Amazon Lex Developer Guide](https://docs.aws.amazon.com/lex/latest/dg/what-is.html). For a quickstart, see [Getting Started](https://alpha-docs-aws.amazon.com/lex/latest/dg/getting-started.html).
36 |
37 | 1. Open `LexSwift.xcworkspace/`.
38 |
39 | 1. Open `awsconfiguration.json` and update the values for Cognito Identity Pool ID (from the value you saved above) and Cognito region for Cognito Identity Pool ID (for example us-east-1).
40 |
41 | ```json
42 | "CredentialsProvider": {
43 | "CognitoIdentity": {
44 | "Default": {
45 | "PoolId": "CHANGE_ME",
46 | "Region": "CHANGE_ME"
47 | }
48 | }
49 | }
50 | ```
51 |
52 | 1. Open `Constants.swift` and update the following lines with the appropriate constants:
53 |
54 | ```swift
55 | let LexRegion = AWSRegionType.Unknown // Change this to your Lex region (most are currently AWSRegionType.USEast1)
56 | let BotName = "BotName" // Put your bot name here
57 | let BotAlias = "$LATEST" // You can leave this if you always want to use the latest version of your bot or put the version
58 | ```
59 |
60 | 1. Build and run the sample app.
61 |
--------------------------------------------------------------------------------
/Lex-Sample/Swift/awsconfiguration.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "1.0",
3 | "IdentityManager": {
4 | "Default": {}
5 | },
6 | "CredentialsProvider": {
7 | "CognitoIdentity": {
8 | "Default": {
9 | "PoolId": "CHANGE_ME",
10 | "Region": "CHANGE_ME"
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Version 2 of AWS SDK Sample for iOS
2 |
3 | Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 |
5 | This product includes software developed by Amazon Technologies, Inc (http://www.amazon.com/).
6 |
7 | Licensed under the Apache License Version 2.0
8 |
9 | See the License for the specific language governing permissions and limitations under the License.
10 |
11 | **********************
12 | THIRD PARTY COMPONENTS
13 | **********************
14 |
15 | This software includes third party software subject to the following copyrights:
16 | - ELCImagePickerController - Copyright (c) 2010 ELC Technologies - The MIT License
17 | - JTSImageViewController - Copyright (c) 2014 Jared Sinclair - MIT license
18 |
19 | The licenses for these third party components are included in the License file.
20 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '12.0'
2 | use_frameworks!
3 |
4 | target 'PollySample' do
5 | pod 'AWSMobileClient'
6 | pod 'AWSPolly'
7 | end
8 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSCore
18 | import AWSMobileClient
19 |
20 | @UIApplicationMain
21 | class AppDelegate: UIResponder, UIApplicationDelegate {
22 |
23 | var window: UIWindow?
24 |
25 |
26 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
27 | AWSMobileClient.sharedInstance().initialize { (userState, error) in
28 | guard error == nil else {
29 | print("AWSMobileClient initialization failed. Error: \(error!.localizedDescription)")
30 | return
31 | }
32 | print("AWSMobileClient initialized.")
33 | }
34 |
35 | return true
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/PollySample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/README.md:
--------------------------------------------------------------------------------
1 | # The Amazon Polly Sample
2 |
3 | This sample demonstrates use of the Amazon Polly APIs to retrieve list of voices and generate speech using the given voice. It uses Cognito authentication in conjunction with Amazon Polly in order to authenticate to the Amazon Polly service. The user is presented with a list of voices which is retrieved when the application loads.
4 |
5 | ## Requirements
6 |
7 | * Xcode 9.2 and later
8 | * iOS 8 and later
9 |
10 | ## Using the Sample
11 |
12 | 1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods:
13 |
14 | sudo gem install cocoapods
15 | pod setup
16 |
17 | 1. To install the AWS Mobile SDK for iOS, change the current directory to the one with your **Podfile** in it and run the following command:
18 |
19 | pod install
20 |
21 | 1. This sample requires Cognito to authorize to Amazon Polly. Use Amazon Cognito to create a new identity pool:
22 | 1. In the [Amazon Cognito Console](https://console.aws.amazon.com/cognito/), press the `Manage Federated Identities` button and on the resulting page press the `Create new identity pool` button.
23 | 1. Give your identity pool a name and ensure that `Enable access to unauthenticated identities` under the `Unauthenticated identities` section is checked. This allows the sample application to assume the unauthenticated role associated with this identity pool. Press the `Create Pool` button to create your identity pool.
24 |
25 | **Important**: see note below on unauthenticated user access.
26 |
27 | 1. As part of creating the identity pool, Cognito will setup two roles in [Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/home#roles). These will be named something similar to: `Cognito_PoolNameAuth_Role` and `Cognito_PoolNameUnauth_Role`. You can view them by pressing the `View Details` button. Now press the `Allow` button to create the roles.
28 | 1. Save the `Identity pool ID` value that shows up in red in the "Getting started with Amazon Cognito" page, it should look similar to: `us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" and note the region that is being used. These will be used in the application code later.
29 | 1. Now we will attach a policy to the unauthenticated role which has permissions to access the required Amazon Polly API. This is done by attaching an IAM Policy to the unauthenticated role in the [IAM Console](https://console.aws.amazon.com/iam/home#roles). First, search for the unauth role that you created in step 3 above (named something similar to `Cognito_PoolNameUnauth_Role`) and select its hyperlink. In the resulting "Summary" page press the `Attach Policy` button in the "Permissions" tab.
30 | 1. Search for "polly" and check the box next to the policy named `AmazonPollyFullAccess` and then press the `Attach Policy` button. This policy allows the application to perform all operations on the Amazon Polly service.
31 |
32 | More information on AWS IAM roles and policies can be found [here](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html). More information on Amazon Polly policies can be found [here](http://docs.aws.amazon.com/polly/latest/dg/using-identity-based-policies.html).
33 |
34 | **Note**: To keep this example simple it makes use of unauthenticated users in the identity pool. This can be used for getting started and prototypes but unauthenticated users should typically only be given read-only permissions in production applications. More information on Cognito identity pools including the Cognito developer guide can be found [here](http://aws.amazon.com/cognito/).
35 |
36 | 1. Open `PollySample.xcworkspace`.
37 |
38 | 1. Open `awsconfiguration.json` and update the values for Cognito Identity Pool ID (from the value you saved above) and the region value for CognitoIdentity, Polly and PollySynthesizeSpeechUrlBuilder (for example us-east-1).
39 |
40 | ```json
41 | "CredentialsProvider": {
42 | "CognitoIdentity": {
43 | "Default": {
44 | "PoolId": "CHANGE_ME",
45 | "Region": "CHANGE_ME"
46 | }
47 | }
48 | },
49 | "Polly": {
50 | "Default": {
51 | "Region": "CHANGE_ME"
52 | }
53 | },
54 | "PollySynthesizeSpeechUrlBuilder": {
55 | "Default": {
56 | "Region": "CHANGE_ME"
57 | }
58 | }
59 | ```
60 |
61 | 1. Build and run the sample app.
62 |
63 | The app will automatically query Amazon Polly for the list of voices and synthesize text with the selected voice.
64 |
--------------------------------------------------------------------------------
/Polly-Sample/Swift/awsconfiguration.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "1.0",
3 | "IdentityManager": {
4 | "Default": {}
5 | },
6 | "CredentialsProvider": {
7 | "CognitoIdentity": {
8 | "Default": {
9 | "PoolId": "CHANGE_ME",
10 | "Region": "CHANGE_ME"
11 | }
12 | }
13 | },
14 | "Polly": {
15 | "Default": {
16 | "Region": "CHANGE_ME"
17 | }
18 | },
19 | "PollySynthesizeSpeechUrlBuilder": {
20 | "Default": {
21 | "Region": "CHANGE_ME"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The AWS SDK for iOS Samples
2 |
3 | This repository has samples that demonstrate various aspects of the [AWS SDK for iOS](https://github.com/aws-amplify/aws-sdk-ios).
4 |
5 | ### Resources
6 |
7 | * [Developer Guide for AWS SDK for iOS](https://aws-amplify.github.io/docs/ios/start)
8 |
9 | Please refer to **README.md** in each sample directory for more specific instructions.
10 |
11 | ### List of Samples
12 |
13 | * S3TransferUtility-Sample ([Swift](https://github.com/awslabs/aws-sdk-ios-samples/tree/main/S3TransferUtility-Sample/Swift/), [Objective-C](https://github.com/awslabs/aws-sdk-ios-samples/tree/main/S3TransferUtility-Sample/Objective-C/)). This is a sample mobile application that demonstrates how to use the Amazon S3 PreSigned URL Builder to download / upload files in background. Involved AWS Services are:
14 | + Amazon S3
15 | + Amazon Cognito Identity
16 |
17 | * IoT-Sample ([Swift](https://github.com/awslabs/aws-sdk-ios-samples/tree/main/IoT-Sample/Swift/)). This is a sample mobile application that demonstrates how to publish and subscribe to data using AWS IoT. Involved AWS Services are:
18 | + Amazon AWS IoT
19 | + Amazon Cognito Identity
20 |
21 | * Lex-Sample ([Objective-C](https://github.com/awslabs/aws-sdk-ios-samples/tree/main/Lex-Sample/ObjC/), [Swift](https://github.com/awslabs/aws-sdk-ios-samples/tree/main/Lex-Sample/swift-3/)). This is a sample mobile application that demonstrates how to use text to text chat and voice to voice chat using Amazon Lex. Involved AWS Services are:
22 | + Amazon Lex
23 | + Amazon Cognito Identity
24 |
25 | * Polly-Sample ([Swift](https://github.com/awslabs/aws-sdk-ios-samples/tree/main/Polly-Sample/Swift/)). This is a sample mobile application that demonstrates how to get the list of voices and synthesize speech using Amazon Polly. Involved AWS Services are:
26 | + Amazon Polly
27 | + Amazon Cognito Identity
28 |
29 | ### Getting Help
30 |
31 | We use [AWS iOS SDK GitHub issues](https://github.com/aws-amplify/aws-sdk-ios/issues) for tracking questions, bugs, and feature requests.
32 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/Podfile:
--------------------------------------------------------------------------------
1 | ENV['SWIFT_VERSION'] = '5'
2 | platform :ios, '12.0'
3 | use_frameworks!
4 |
5 | target 'S3TransferUtilitySampleObjC' do
6 | pod 'AWSS3'
7 | end
8 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/README.md:
--------------------------------------------------------------------------------
1 | # The Amazon S3 Background Transfer Sample
2 |
3 | This sample demonstrates how to use `AWSS3TransferUtility` to download / upload files in background.
4 |
5 | ## Requirements
6 |
7 | * Xcode 9.2 and later
8 | * iOS 8 and later
9 |
10 | ## Using the Sample
11 |
12 | 1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods:
13 |
14 | sudo gem install cocoapods
15 | pod setup
16 |
17 | 1. To install the AWS Mobile SDK for iOS, change the current directory to the one with your **Podfile** in it and run the following command:
18 |
19 | pod install
20 |
21 | 1. Create an Amazon S3 bucket. (For details on creating a bucket in the Amazon S3 console, see [Create a Bucket](http://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html).)
22 |
23 | 1. Upload a image in the bucket. Open `Constants.m` or `Constants.swift` and update the following lines with the appropriate constants:
24 |
25 | Swift
26 |
27 | let S3BucketName: String = "YourS3BucketName"
28 |
29 | Objective-C
30 |
31 | NSString *const S3BucketName = @"YourS3BucketName";
32 | NSString *const S3DownloadKeyName = @"YourDownloadKeyName";
33 |
34 | 1. This sample requires Cognito to authorize to Amazon S3 in order to access the bucket. Use Amazon Cognito to create a new identity pool:
35 | 1. In the [Amazon Cognito Console](https://console.aws.amazon.com/cognito/), press the `Manage Federated Identities` button and on the resulting page press the `Create new identity pool` button.
36 | 1. Give your identity pool a name and ensure that `Enable access to unauthenticated identities` under the `Unauthenticated identities` section is checked. This allows the sample application to assume the unauthenticated role associated with this identity pool. Press the `Create Pool` button to create your identity pool.
37 |
38 | **Important**: see note below on unauthenticated user access.
39 |
40 | 1. As part of creating the identity pool, Cognito will setup two roles in [Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/home#roles). These will be named something similar to: `Cognito_PoolNameAuth_Role` and `Cognito_PoolNameUnauth_Role`. You can view them by pressing the `View Details` button. Now press the `Allow` button to create the roles.
41 | 1. Save the `Identity pool ID` value that shows up in red in the "Getting started with Amazon Cognito" page, it should look similar to: `us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" and note the region that is being used. These will be used in the application code later.
42 | 1. Now we will attach a policy to the unauthenticated role which has permissions to access the required Amazon S3 API. This is done by attaching an IAM Policy to the unauthenticated role in the [IAM Console](https://console.aws.amazon.com/iam/home#roles). First, search for the unauth role that you created in step 3 above (named something similar to `Cognito_PoolNameUnauth_Role`) and select its hyperlink. In the resulting "Summary" page press the `Attach Policy` button in the "Permissions" tab.
43 | 1. Search for "S3" and check the box next to the policy named `AmazonS3FullAccess` and then press the `Attach Policy` button. This policy allows the application to perform all operations on the Amazon Polly service.
44 |
45 | More information on AWS IAM roles and policies can be found [here](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html). More information on Amazon S3 policies can be found [here](http://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html).
46 |
47 | **Note**: To keep this example simple it makes use of unauthenticated users in the identity pool. This can be used for getting started and prototypes but unauthenticated users should typically only be given read-only permissions in production applications. More information on Cognito identity pools including the Cognito developer guide can be found [here](http://aws.amazon.com/cognito/).
48 |
49 | 1. Open `S3BackgroundTransferSampleObjC.xcworkspace` or `S3BackgroundTransferSampleSwift.xcworkspace`.
50 |
51 | 1. Open `Info.plist` and update the following lines with the your values:
52 |
53 | **AWS --> CredentialsProvider --> CognitoIdentity --> Default --> PoolId** (put your Cognito IdentityPoolID here)
54 |
55 | **AWS --> CredentialsProvider --> CognitoIdentity --> Default --> Region** (for example: USEast1)
56 |
57 | **AWS --> S3TransferUtility --> Default --> Region** (for example: USEast1)
58 |
59 | 1. Build and run the sample app.
60 |
61 | ## NOTES
62 |
63 | 1. The TransferUtility uses a `NSURL Background Session` to upload and download files. To make sure that the transfers continue to run when the app is moved to the background, the `handleEventsForBackgroundURLSession` method has to be implemented in the `AppDelegate`. The sample implements this as follows
64 |
65 | Swift
66 |
67 | func application(_ application: UIApplication,
68 | handleEventsForBackgroundURLSession identifier: String,
69 | completionHandler: @escaping () -> Void) {
70 |
71 | //provide the completionHandler to the TransferUtility to support background transfers.
72 | AWSS3TransferUtility.interceptApplication(application,
73 | handleEventsForBackgroundURLSession: identifier,
74 | completionHandler: completionHandler)
75 | }
76 |
77 | Objective-C
78 |
79 | (void) application:(UIApplication *)application
80 | handleEventsForBackgroundURLSession:(NSString *)identifier
81 | completionHandler:(void (^)(void))completionHandler {
82 |
83 | //provide the completionHandler to the TransferUtility to support background transfers.
84 | [AWSS3TransferUtility interceptApplication:application
85 | handleEventsForBackgroundURLSession:identifier
86 | completionHandler:completionHandler];
87 | }
88 |
89 | 1. If, you get a bunch of warnings that look similar to the one below when you run the sample and try doing an upload:
90 |
91 | Function boringssl_session_errorlog: line 2868 [boringssl_session_write] SSL_ERROR_SYSCALL(5): operation failed externally to the library
92 | 2017-12-22 10:46:37.105342-0800 S3TransferManagerSampleSwift[59012:3381604] [BoringSSL]
93 |
94 | You can disable OS logging in Xcode to make them go away. With your project window open, go to Project -> Scheme -> Edit Scheme... and add "OS_ACTIVITY_MODE" to the Environment Variables section and set its value to "disable". When you rerun the app those warnings should now not appear.
95 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import
17 |
18 | @interface AppDelegate : UIResponder
19 |
20 | @property (strong, nonatomic) UIWindow *window;
21 | @property (copy) void (^backgroundDownloadSessionCompletionHandler)(void);
22 | @property (copy) void (^backgroundUploadSessionCompletionHandler)(void);
23 |
24 | @end
25 |
26 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import "AppDelegate.h"
17 | #import
18 | #import "Constants.h"
19 |
20 | @implementation AppDelegate
21 |
22 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
23 | return YES;
24 | }
25 |
26 | - (void) application:(UIApplication *)application
27 | handleEventsForBackgroundURLSession:(NSString *)identifier
28 | completionHandler:(void (^)(void))completionHandler {
29 |
30 | //provide the completionHandler to the TransferUtility to support background transfers.
31 | [AWSS3TransferUtility interceptApplication:application
32 | handleEventsForBackgroundURLSession:identifier
33 | completionHandler:completionHandler];
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Constants.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import
17 | @import AWSCore;
18 |
19 | FOUNDATION_EXPORT NSString *const S3BucketName;
20 | FOUNDATION_EXPORT NSString *const S3DownloadKeyName;
21 |
22 | FOUNDATION_EXPORT NSString *const S3UploadKeyName;
23 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Constants.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import "Constants.h"
17 |
18 | #warning To run this sample correctly, you must set the following constants.
19 | NSString *const S3BucketName = @"YourS3BucketNameHere"; // Update this to your bucket name
20 | NSString *const S3DownloadKeyName = @"S3DownloadKeyName"; // Name of file to be downloaded
21 | NSString *const S3UploadKeyName = @"uploadfileobj.txt"; // Name of file to be uploaded
22 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/FirstViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import
17 |
18 | @interface FirstViewController : UIViewController
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/FirstViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import "FirstViewController.h"
17 | #import
18 | #import "Constants.h"
19 |
20 | @interface FirstViewController ()
21 |
22 | @property (weak, nonatomic) IBOutlet UIProgressView *progressView;
23 | @property (weak, nonatomic) IBOutlet UILabel *statusLabel;
24 |
25 | @end
26 |
27 | @implementation FirstViewController
28 |
29 | - (void)viewDidLoad {
30 | [super viewDidLoad];
31 | dispatch_async(dispatch_get_main_queue(), ^{
32 | self.statusLabel.text = @"";
33 | self.progressView.progress = 0;
34 | });
35 |
36 | }
37 |
38 | - (IBAction)start:(id)sender {
39 | dispatch_async(dispatch_get_main_queue(), ^{
40 | self.statusLabel.text = @"Creating a test file...";
41 | self.progressView.progress = 0;
42 | });
43 |
44 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
45 | // Create a test file in the temporary directory
46 | NSMutableString *dataString = [NSMutableString new];
47 | for (int32_t i = 1; i < 10000000; i++) {
48 | [dataString appendFormat:@"%d\n", i];
49 | }
50 |
51 | [self uploadData:[dataString dataUsingEncoding:NSUTF8StringEncoding]];
52 | });
53 | }
54 |
55 | - (void)uploadData:(NSData *)testData {
56 | //Initalize the screen elements
57 | dispatch_async(dispatch_get_main_queue(), ^{
58 | self.progressView.progress = 0;
59 | self.statusLabel.text = @"";
60 | });
61 |
62 |
63 | __weak FirstViewController *weakSelf = self;
64 |
65 | //Create the completion handler for the transfer
66 | AWSS3TransferUtilityUploadCompletionHandlerBlock completionHandler = ^(AWSS3TransferUtilityUploadTask *task, NSError *error) {
67 | dispatch_async(dispatch_get_main_queue(), ^{
68 | if (error) {
69 | weakSelf.statusLabel.text = @"Failed to Upload";
70 | } else {
71 | weakSelf.statusLabel.text = @"Successfully Uploaded";
72 | weakSelf.progressView.progress = 1.0;
73 | }
74 | });
75 | };
76 |
77 | //Create the TransferUtility expression and add the progress block to it.
78 | //This would be needed to report on progress tracking
79 | AWSS3TransferUtilityUploadExpression *expression = [AWSS3TransferUtilityUploadExpression new];
80 | expression.progressBlock = ^(AWSS3TransferUtilityTask *task, NSProgress *progress) {
81 | dispatch_async(dispatch_get_main_queue(), ^{
82 | if ( weakSelf.progressView.progress < progress.fractionCompleted) {
83 | weakSelf.progressView.progress = progress.fractionCompleted;
84 | }
85 | });
86 | };
87 |
88 | AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];
89 | [[transferUtility uploadData:testData
90 | bucket:S3BucketName
91 | key:S3UploadKeyName
92 | contentType:@"text/plain"
93 | expression:expression
94 | completionHandler:completionHandler] continueWithBlock:^id(AWSTask *task) {
95 | if (task.error) {
96 | NSLog(@"Error: %@", task.error);
97 | }
98 | if (task.result) {
99 | dispatch_async(dispatch_get_main_queue(), ^{
100 | self.statusLabel.text = @"Uploading...";
101 | });
102 | }
103 | return nil;
104 | }];
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/first.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "first.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/first.imageset/first.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/first.imageset/first.pdf
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/second.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "second.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/second.imageset/second.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Images.xcassets/second.imageset/second.pdf
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIcons
10 |
11 | CFBundleIcons~ipad
12 |
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | $(PRODUCT_NAME)
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1
27 | LSRequiresIPhoneOS
28 |
29 | NSAppTransportSecurity
30 |
31 | NSExceptionDomains
32 |
33 | amazonaws.com
34 |
35 | NSIncludesSubdomains
36 |
37 | NSThirdPartyExceptionMinimumTLSVersion
38 | TLSv1.0
39 | NSThirdPartyExceptionRequiresForwardSecrecy
40 |
41 |
42 | amazonaws.com.cn
43 |
44 | NSIncludesSubdomains
45 |
46 | NSThirdPartyExceptionMinimumTLSVersion
47 | TLSv1.0
48 | NSThirdPartyExceptionRequiresForwardSecrecy
49 |
50 |
51 |
52 |
53 | UILaunchStoryboardName
54 | Launch Screen
55 | UIMainStoryboardFile
56 | Main
57 | UIRequiredDeviceCapabilities
58 |
59 | armv7
60 |
61 | UIStatusBarTintParameters
62 |
63 | UINavigationBar
64 |
65 | Style
66 | UIBarStyleDefault
67 | Translucent
68 |
69 |
70 |
71 | UISupportedInterfaceOrientations
72 |
73 | UIInterfaceOrientationPortrait
74 | UIInterfaceOrientationLandscapeLeft
75 | UIInterfaceOrientationLandscapeRight
76 |
77 | AWS
78 |
79 | CredentialsProvider
80 |
81 | CognitoIdentity
82 |
83 | Default
84 |
85 | PoolId
86 | YourCognitoIdentityPoolId
87 | Region
88 | YourCognitoIdentityRegion
89 |
90 |
91 |
92 | S3TransferUtility
93 |
94 | Default
95 |
96 | Region
97 | YourS3Region
98 |
99 |
100 |
101 | NSPhotoLibraryUsageDescription
102 | Give permission to let the app get access to the images from the Photo Library
103 |
104 |
105 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/SecondViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import
17 |
18 | @interface SecondViewController : UIViewController
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/SecondViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import "SecondViewController.h"
17 | #import "AppDelegate.h"
18 | #import
19 | #import "Constants.h"
20 |
21 | @interface SecondViewController ()
22 |
23 | @property (weak, nonatomic) IBOutlet UIImageView *imageView;
24 | @property (weak, nonatomic) IBOutlet UIProgressView *progressView;
25 | @property (weak, nonatomic) IBOutlet UILabel *statusLabel;
26 |
27 | @end
28 |
29 | @implementation SecondViewController
30 |
31 | - (void)viewDidLoad {
32 | [super viewDidLoad];
33 | dispatch_async(dispatch_get_main_queue(), ^{
34 | self.progressView.progress = 0;
35 | self.statusLabel.text = @"";
36 | });
37 |
38 |
39 | }
40 |
41 | - (IBAction)start:(id)sender {
42 |
43 | //Initalize the screen elements
44 | dispatch_async(dispatch_get_main_queue(), ^{
45 | self.progressView.progress = 0;
46 | self.statusLabel.text = @"";
47 | self.imageView.image = nil;
48 | });
49 |
50 | __weak SecondViewController *weakSelf = self;
51 |
52 | //Create the completion handler for the transfer
53 | AWSS3TransferUtilityDownloadCompletionHandlerBlock completionHandler = ^(AWSS3TransferUtilityDownloadTask *task, NSURL *location, NSData *data, NSError *error) {
54 | dispatch_async(dispatch_get_main_queue(), ^{
55 | if (error) {
56 | weakSelf.statusLabel.text = @"Failed to Download";
57 | }
58 | if (data) {
59 | weakSelf.statusLabel.text = @"Successfully Downloaded";
60 | weakSelf.imageView.image = [UIImage imageWithData:data];
61 | weakSelf.progressView.progress = 1.0;
62 | }
63 | });
64 | };
65 |
66 |
67 | //Create the TransferUtility expression and add the progress block to it.
68 | //This would be needed to report on progress tracking
69 | AWSS3TransferUtilityDownloadExpression *expression = [AWSS3TransferUtilityDownloadExpression new];
70 | expression.progressBlock = ^(AWSS3TransferUtilityTask *task, NSProgress *progress) {
71 | dispatch_async(dispatch_get_main_queue(), ^{
72 | weakSelf.progressView.progress = progress.fractionCompleted;
73 | });
74 | };
75 |
76 |
77 | AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];
78 | [[transferUtility downloadDataFromBucket:S3BucketName
79 | key:S3DownloadKeyName
80 | expression:expression
81 | completionHandler:completionHandler] continueWithBlock:^id(AWSTask *task) {
82 | if (task.error) {
83 | NSLog(@"Error: %@", task.error);
84 | }
85 | if (task.result) {
86 | dispatch_async(dispatch_get_main_queue(), ^{
87 | self.statusLabel.text = @"Downloading...";
88 | });
89 | }
90 |
91 | return nil;
92 | }];
93 | }
94 |
95 | @end
96 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/TemplateIcon2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/TemplateIcon2x.png
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3BackgroundTransferSampleObjC/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | #import
17 | #import "AppDelegate.h"
18 |
19 | int main(int argc, char * argv[]) {
20 | @autoreleasepool {
21 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3TransferUtilitySampleObjC.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Objective-C/S3TransferUtilitySampleObjC.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/.gitignore:
--------------------------------------------------------------------------------
1 | amplify
2 | amplify/\#current-cloud-backend
3 | amplify/.config/local-*
4 | amplify/backend/amplify-meta.json
5 | amplify/backend/awscloudformation
6 | build/
7 | dist/
8 | node_modules/
9 | aws-exports.js
10 | awsconfiguration.json
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '12.0'
2 | use_frameworks!
3 |
4 | target 'S3TransferUtilitySampleSwift' do
5 | pod 'AWSMobileClient'
6 | pod 'AWSS3'
7 | end
8 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/README.md:
--------------------------------------------------------------------------------
1 | # The Amazon S3 Background Transfer Sample
2 |
3 | This sample demonstrates how to use `AWSS3TransferUtility` to download / upload files in background.
4 |
5 | ## Requirements
6 |
7 | * Xcode 9.2 and later
8 | * iOS 8 and later
9 |
10 | ## Using the Sample
11 |
12 | 1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods:
13 |
14 | sudo gem install cocoapods
15 | pod setup
16 |
17 | 1. To install the AWS Mobile SDK for iOS, change the current directory to the one with your **Podfile** in it and run the following command:
18 |
19 | pod install
20 |
21 | 1. Create new AWS backend resources and pull the AWS services configuration into the app by running the following command:
22 |
23 | amplify init # accept default options to get started
24 | amplify push # create the configuration file
25 |
26 | 1. Add the required S3 resource to your app's cloud-enabled backend using the following CLI command:
27 |
28 | amplify add storage
29 |
30 | 1. Choose `Content` as your storage service.
31 |
32 | ❯ Content (Images, audio, video, etc.)
33 |
34 | 1. The CLI walks you through the options to enable Auth (if not enabled previously), to name your S3 bucket, and to decide who should have access (select Auth and guest users and read/write for both auth and guest users).
35 |
36 | 1. Confirm that you have storage and auth set up with the following command:
37 |
38 | amplify status
39 |
40 | 1. Create the specified backend by running the following command:
41 |
42 | amplify push
43 |
44 | 1. Open `S3TransferUtilitySampleSwift.xcworkspace`.
45 |
46 | 1. Add the cli-generated `awsconfiguration.json` by right-clicking the project in Xcode project navigator, selecting `Add Files to "S3TransferUtilitySampleSwift"..."` and following instructions in the dialog window.
47 |
48 | 1. Build and run the sample app.
49 |
50 | ## NOTES
51 |
52 | 1. The TransferUtility uses a `NSURL Background Session` to upload and download files. To make sure that the transfers continue to run when the app is moved to the background, the `handleEventsForBackgroundURLSession` method has to be implemented in the `AppDelegate`. The sample implements this as follows
53 |
54 | Swift
55 |
56 | func application(_ application: UIApplication,
57 | handleEventsForBackgroundURLSession identifier: String,
58 | completionHandler: @escaping () -> Void) {
59 |
60 | //provide the completionHandler to the TransferUtility to support background transfers.
61 | AWSS3TransferUtility.interceptApplication(application,
62 | handleEventsForBackgroundURLSession: identifier,
63 | completionHandler: completionHandler)
64 | }
65 |
66 | Objective-C
67 |
68 | (void) application:(UIApplication *)application
69 | handleEventsForBackgroundURLSession:(NSString *)identifier
70 | completionHandler:(void (^)(void))completionHandler {
71 |
72 | //provide the completionHandler to the TransferUtility to support background transfers.
73 | [AWSS3TransferUtility interceptApplication:application
74 | handleEventsForBackgroundURLSession:identifier
75 | completionHandler:completionHandler];
76 | }
77 |
78 | 1. If, you get a bunch of warnings that look similar to the one below when you run the sample and try doing an upload:
79 |
80 | Function boringssl_session_errorlog: line 2868 [boringssl_session_write] SSL_ERROR_SYSCALL(5): operation failed externally to the library
81 | 2017-12-22 10:46:37.105342-0800 S3TransferManagerSampleSwift[59012:3381604] [BoringSSL]
82 |
83 | You can disable OS logging in Xcode to make them go away. With your project window open, go to Project -> Scheme -> Edit Scheme... and add "OS_ACTIVITY_MODE" to the Environment Variables section and set its value to "disable". When you rerun the app those warnings should now not appear.
84 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSS3
18 | import AWSMobileClient
19 |
20 | @UIApplicationMain
21 | class AppDelegate: UIResponder, UIApplicationDelegate {
22 |
23 | var window: UIWindow?
24 |
25 | func application(_ application: UIApplication,
26 | handleEventsForBackgroundURLSession identifier: String,
27 | completionHandler: @escaping () -> Void) {
28 |
29 | AWSMobileClient.sharedInstance().initialize { (userState, error) in
30 | guard error == nil else {
31 | print("Error initializing AWSMobileClient. Error: \(error!.localizedDescription)")
32 | return
33 | }
34 | print("AWSMobileClient initialized.")
35 | }
36 |
37 | //provide the completionHandler to the TransferUtility to support background transfers.
38 | AWSS3TransferUtility.interceptApplication(application,
39 | handleEventsForBackgroundURLSession: identifier,
40 | completionHandler: completionHandler)
41 | }
42 |
43 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Constants.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import Foundation
17 | import AWSCore
18 |
19 | // Warning: To run this sample correctly, you must set the following constants.
20 |
21 | let S3DownloadKeyName: String = "public/test-image.png" // Name of file to be downloaded
22 | let S3UploadKeyName: String = "public/test-image.png" // Name of file to be uploaded
23 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/DownloadViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSS3
18 |
19 | class DownloadViewController: UIViewController{
20 |
21 | @IBOutlet var imageView: UIImageView!
22 | @IBOutlet var progressView: UIProgressView!
23 | @IBOutlet var statusLabel: UILabel!
24 |
25 | @objc var completionHandler: AWSS3TransferUtilityDownloadCompletionHandlerBlock?
26 |
27 | @objc lazy var transferUtility = {
28 | AWSS3TransferUtility.default()
29 | }()
30 |
31 | override func viewDidLoad() {
32 | super.viewDidLoad()
33 | // Do any additional setup after loading the view, typically from a nib.
34 |
35 | self.progressView.progress = 0.0;
36 | self.statusLabel.text = "Ready"
37 | }
38 |
39 | override func didReceiveMemoryWarning() {
40 | super.didReceiveMemoryWarning()
41 | // Dispose of any resources that can be recreated.
42 | }
43 |
44 | @IBAction func start(_ sender: UIButton) {
45 |
46 | DispatchQueue.main.async(execute: {
47 | self.statusLabel.text = ""
48 | self.progressView.progress = 0
49 | })
50 |
51 | self.imageView.image = nil;
52 |
53 | let expression = AWSS3TransferUtilityDownloadExpression()
54 | expression.progressBlock = {(task, progress) in
55 | DispatchQueue.main.async(execute: {
56 | if (self.progressView.progress < Float(progress.fractionCompleted)) {
57 | self.progressView.progress = Float(progress.fractionCompleted)
58 | }
59 | })
60 | }
61 |
62 | self.completionHandler = { (task, location, data, error) -> Void in
63 | DispatchQueue.main.async(execute: {
64 | if let error = error {
65 | NSLog("Failed with error: \(error)")
66 | self.statusLabel.text = "Failed"
67 | }
68 | else if(self.progressView.progress != 1.0) {
69 | self.statusLabel.text = "Failed"
70 | }
71 | else{
72 | self.statusLabel.text = "Success"
73 | self.imageView.image = UIImage(data: data!)
74 | }
75 | })
76 | }
77 |
78 | transferUtility.downloadData(
79 | forKey: S3DownloadKeyName,
80 | expression: expression,
81 | completionHandler: completionHandler).continueWith { (task) -> AnyObject? in
82 | if let error = task.error {
83 | NSLog("Error: %@",error.localizedDescription);
84 | DispatchQueue.main.async(execute: {
85 | self.statusLabel.text = "Failed"
86 | })
87 | }
88 |
89 | if let _ = task.result {
90 | DispatchQueue.main.async(execute: {
91 | self.statusLabel.text = "Downloading..."
92 | })
93 | NSLog("Download Starting!")
94 | // Do something with uploadTask.
95 | }
96 | return nil;
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/first.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "first.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/first.imageset/first.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/first.imageset/first.pdf
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/second.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "second.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/second.imageset/second.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Images.xcassets/second.imageset/second.pdf
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UILaunchStoryboardName
6 | Launch Screen
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSExceptionDomains
30 |
31 | amazonaws.com
32 |
33 | NSThirdPartyExceptionMinimumTLSVersion
34 | TLSv1.0
35 | NSThirdPartyExceptionRequiresForwardSecrecy
36 |
37 | NSIncludesSubdomains
38 |
39 |
40 | amazonaws.com.cn
41 |
42 | NSThirdPartyExceptionMinimumTLSVersion
43 | TLSv1.0
44 | NSThirdPartyExceptionRequiresForwardSecrecy
45 |
46 | NSIncludesSubdomains
47 |
48 |
49 |
50 |
51 | UIMainStoryboardFile
52 | Main
53 | UIRequiredDeviceCapabilities
54 |
55 | armv7
56 |
57 | UIStatusBarTintParameters
58 |
59 | UINavigationBar
60 |
61 | Style
62 | UIBarStyleDefault
63 | Translucent
64 |
65 |
66 |
67 | UISupportedInterfaceOrientations
68 |
69 | UIInterfaceOrientationPortrait
70 | UIInterfaceOrientationLandscapeLeft
71 | UIInterfaceOrientationLandscapeRight
72 |
73 | NSPhotoLibraryUsageDescription
74 | Give permission to let the app get access to the images from the Photo Library
75 |
76 |
77 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/UploadViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import UIKit
17 | import AWSS3
18 |
19 | class UploadViewController: UIViewController, UINavigationControllerDelegate {
20 |
21 | @IBOutlet var progressView: UIProgressView!
22 | @IBOutlet var statusLabel: UILabel!
23 |
24 | @objc var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
25 | @objc var progressBlock: AWSS3TransferUtilityProgressBlock?
26 |
27 | @objc let imagePicker = UIImagePickerController()
28 |
29 | @objc lazy var transferUtility = {
30 | AWSS3TransferUtility.default()
31 | }()
32 |
33 | override func viewDidLoad() {
34 | super.viewDidLoad()
35 | // Do any additional setup after loading the view, typically from a nib.
36 |
37 | self.progressView.progress = 0.0;
38 | self.statusLabel.text = "Ready"
39 | self.imagePicker.delegate = self
40 |
41 | self.progressBlock = {(task, progress) in
42 | DispatchQueue.main.async(execute: {
43 | if (self.progressView.progress < Float(progress.fractionCompleted)) {
44 | self.progressView.progress = Float(progress.fractionCompleted)
45 | }
46 | })
47 | }
48 |
49 | self.completionHandler = { (task, error) -> Void in
50 | DispatchQueue.main.async(execute: {
51 | if let error = error {
52 | print("Failed with error: \(error)")
53 | self.statusLabel.text = "Failed"
54 | }
55 | else if(self.progressView.progress != 1.0) {
56 | self.statusLabel.text = "Failed"
57 | NSLog("Error: Failed - Likely due to invalid region / filename")
58 | }
59 | else{
60 | self.statusLabel.text = "Success"
61 | }
62 | })
63 | }
64 | }
65 |
66 | @IBAction func selectAndUpload(_ sender: UIButton) {
67 | imagePicker.allowsEditing = false
68 | imagePicker.sourceType = .photoLibrary
69 |
70 | present(imagePicker, animated: true, completion: nil)
71 | }
72 |
73 | @objc func uploadImage(with data: Data) {
74 | let expression = AWSS3TransferUtilityUploadExpression()
75 | expression.progressBlock = progressBlock
76 |
77 | DispatchQueue.main.async(execute: {
78 | self.statusLabel.text = ""
79 | self.progressView.progress = 0
80 | })
81 |
82 | transferUtility.uploadData(
83 | data,
84 | key: S3UploadKeyName,
85 | contentType: "image/png",
86 | expression: expression,
87 | completionHandler: completionHandler).continueWith { (task) -> AnyObject? in
88 | if let error = task.error {
89 | print("Error: \(error.localizedDescription)")
90 |
91 | DispatchQueue.main.async {
92 | self.statusLabel.text = "Failed"
93 | }
94 | }
95 |
96 | if let _ = task.result {
97 |
98 | DispatchQueue.main.async {
99 | self.statusLabel.text = "Uploading..."
100 | print("Upload Starting!")
101 | }
102 |
103 | // Do something with uploadTask.
104 | }
105 |
106 | return nil;
107 | }
108 | }
109 | }
110 |
111 | extension UploadViewController: UIImagePickerControllerDelegate {
112 |
113 | public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
114 | // Local variable inserted by Swift 4.2 migrator.
115 | let info = convertFromUIImagePickerControllerInfoKeyDictionary(info)
116 |
117 | if "public.image" == info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.mediaType)] as? String {
118 | let image: UIImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.originalImage)] as! UIImage
119 | self.uploadImage(with: image.pngData()!)
120 | }
121 |
122 |
123 | dismiss(animated: true, completion: nil)
124 | }
125 | }
126 |
127 | // Helper function inserted by Swift 4.2 migrator.
128 | fileprivate func convertFromUIImagePickerControllerInfoKeyDictionary(_ input: [UIImagePickerController.InfoKey: Any]) -> [String: Any] {
129 | return Dictionary(uniqueKeysWithValues: input.map {key, value in (key.rawValue, value)})
130 | }
131 |
132 | // Helper function inserted by Swift 4.2 migrator.
133 | fileprivate func convertFromUIImagePickerControllerInfoKey(_ input: UIImagePickerController.InfoKey) -> String {
134 | return input.rawValue
135 | }
136 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3TransferUtilitySampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3TransferUtilitySampleSwift.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3TransferUtilitySampleSwiftUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/S3TransferUtilitySampleSwiftUITests/S3TransferUtilitySampleSwiftUITests.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import XCTest
17 |
18 | class S3TransferUtilitySampleSwiftUITests: XCTestCase {
19 |
20 | override func setUp() {
21 | super.setUp()
22 |
23 | // Put setup code here. This method is called before the invocation of each test method in the class.
24 |
25 | // In UI tests it is usually best to stop immediately when a failure occurs.
26 | continueAfterFailure = false
27 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
28 | XCUIApplication().launch()
29 |
30 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
31 | }
32 |
33 | override func tearDown() {
34 | // Put teardown code here. This method is called after the invocation of each test method in the class.
35 | super.tearDown()
36 | }
37 |
38 | func testButtons() {
39 | // Use recording to get started writing UI tests.
40 | // Use XCTAssert and related functions to verify your tests produce the correct results.
41 |
42 | let app = XCUIApplication()
43 | let tabBarsQuery = app.tabBars
44 | let uploadButton = tabBarsQuery.buttons["Upload"]
45 | uploadButton.tap()
46 | app.buttons["Select Image and Upload"].tap()
47 | let cancelButton = app.navigationBars["Photos"].buttons["Cancel"]
48 | let exists = NSPredicate(format: "exists == 1")
49 |
50 | expectation(for: exists, evaluatedWith: cancelButton, handler: nil)
51 | waitForExpectations(timeout: 5, handler: nil)
52 | cancelButton.tap()
53 | let readyStaticText = app.staticTexts["Ready"]
54 | readyStaticText.tap()
55 | tabBarsQuery.buttons["Download"].tap()
56 | readyStaticText.tap()
57 | uploadButton.tap()
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/S3TransferUtility-Sample/Swift/awsconfiguration.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awslabs/aws-sdk-ios-samples/0343d828361b5b9f21e57d3d23cb6d18f45689a7/S3TransferUtility-Sample/Swift/awsconfiguration.json
--------------------------------------------------------------------------------