diff --git a/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.pbxproj b/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.pbxproj new file mode 100644 index 00000000..1a42b1f3 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.pbxproj @@ -0,0 +1,403 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + A62CEE5B1BF3B50800E9C895 /* SubscribeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A62CEE5A1BF3B50800E9C895 /* SubscribeViewController.swift */; }; + A6867C941BF530A700956B68 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6867C931BF530A700956B68 /* Constants.swift */; }; + A6B39BB51BF3A93600045F73 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6B39BB41BF3A93600045F73 /* AppDelegate.swift */; }; + A6B39BB71BF3A93600045F73 /* ConnectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6B39BB61BF3A93600045F73 /* ConnectionViewController.swift */; }; + A6B39BB91BF3A93600045F73 /* PublishViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6B39BB81BF3A93600045F73 /* PublishViewController.swift */; }; + A6B39BBC1BF3A93600045F73 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A6B39BBA1BF3A93600045F73 /* Main.storyboard */; }; + A6B39BBE1BF3A93600045F73 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A6B39BBD1BF3A93600045F73 /* Assets.xcassets */; }; + A6B39BC11BF3A93600045F73 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A6B39BBF1BF3A93600045F73 /* LaunchScreen.storyboard */; }; + A6CC2A291BFFCB6F00635393 /* IoTSampleTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6CC2A281BFFCB6F00635393 /* IoTSampleTabBarController.swift */; }; + A6E263221C06870D0032B28D /* ConfigurationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E263211C06870D0032B28D /* ConfigurationViewController.swift */; }; + D780C68890E20DA22A5A5484 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 047C61848590B9F3ADAB5CC9 /* libPods.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 047C61848590B9F3ADAB5CC9 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 19CC868788E3FB2186476009 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + 3B90C03514D3F9F7EDF1FF45 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; + A62CEE581BF3AE9700E9C895 /* ObjectiveC-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ObjectiveC-Bridging-Header.h"; path = "IoTSampleSwift/ObjectiveC-Bridging-Header.h"; sourceTree = ""; }; + A62CEE5A1BF3B50800E9C895 /* SubscribeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscribeViewController.swift; sourceTree = ""; }; + A6867C931BF530A700956B68 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + A6B39BB11BF3A93600045F73 /* IoTSampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IoTSampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A6B39BB41BF3A93600045F73 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A6B39BB61BF3A93600045F73 /* ConnectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionViewController.swift; sourceTree = ""; }; + A6B39BB81BF3A93600045F73 /* PublishViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublishViewController.swift; sourceTree = ""; }; + A6B39BBB1BF3A93600045F73 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + A6B39BBD1BF3A93600045F73 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + A6B39BC01BF3A93600045F73 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + A6B39BC21BF3A93600045F73 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = IoTSampleSwift/Info.plist; sourceTree = ""; }; + A6CC2A281BFFCB6F00635393 /* IoTSampleTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IoTSampleTabBarController.swift; sourceTree = ""; }; + A6E263211C06870D0032B28D /* ConfigurationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A6B39BAE1BF3A93600045F73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D780C68890E20DA22A5A5484 /* libPods.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A62CEE591BF3AEA500E9C895 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + A62CEE581BF3AE9700E9C895 /* ObjectiveC-Bridging-Header.h */, + A6B39BC21BF3A93600045F73 /* Info.plist */, + ); + name = "Supporting Files"; + path = ..; + sourceTree = ""; + }; + A6B39BA81BF3A93600045F73 = { + isa = PBXGroup; + children = ( + A6B39BB31BF3A93600045F73 /* IoTSampleSwift */, + A6B39BB21BF3A93600045F73 /* Products */, + DAE09B38C7A74FEC688B429A /* Pods */, + B4948BBFC248DCA3B8694222 /* Frameworks */, + ); + sourceTree = ""; + }; + A6B39BB21BF3A93600045F73 /* Products */ = { + isa = PBXGroup; + children = ( + A6B39BB11BF3A93600045F73 /* IoTSampleSwift.app */, + ); + name = Products; + sourceTree = ""; + }; + A6B39BB31BF3A93600045F73 /* IoTSampleSwift */ = { + isa = PBXGroup; + children = ( + A6867C931BF530A700956B68 /* Constants.swift */, + A6B39BB41BF3A93600045F73 /* AppDelegate.swift */, + A6CC2A281BFFCB6F00635393 /* IoTSampleTabBarController.swift */, + A6B39BB61BF3A93600045F73 /* ConnectionViewController.swift */, + A6B39BB81BF3A93600045F73 /* PublishViewController.swift */, + A6E263211C06870D0032B28D /* ConfigurationViewController.swift */, + A62CEE5A1BF3B50800E9C895 /* SubscribeViewController.swift */, + A6B39BBA1BF3A93600045F73 /* Main.storyboard */, + A6B39BBD1BF3A93600045F73 /* Assets.xcassets */, + A6B39BBF1BF3A93600045F73 /* LaunchScreen.storyboard */, + A62CEE591BF3AEA500E9C895 /* Supporting Files */, + ); + path = IoTSampleSwift; + sourceTree = ""; + }; + B4948BBFC248DCA3B8694222 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 047C61848590B9F3ADAB5CC9 /* libPods.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + DAE09B38C7A74FEC688B429A /* Pods */ = { + isa = PBXGroup; + children = ( + 3B90C03514D3F9F7EDF1FF45 /* Pods.debug.xcconfig */, + 19CC868788E3FB2186476009 /* Pods.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A6B39BB01BF3A93600045F73 /* IoTSampleSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = A6B39BC51BF3A93600045F73 /* Build configuration list for PBXNativeTarget "IoTSampleSwift" */; + buildPhases = ( + DC1F7059CF8DC38C8DFA1A4A /* Check Pods Manifest.lock */, + A6B39BAD1BF3A93600045F73 /* Sources */, + A6B39BAE1BF3A93600045F73 /* Frameworks */, + A6B39BAF1BF3A93600045F73 /* Resources */, + 75F7F940938971BA0FD2C49C /* Copy Pods Resources */, + 4D1E2401B957BD82886A4683 /* Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IoTSampleSwift; + productName = IoTSampleSwift; + productReference = A6B39BB11BF3A93600045F73 /* IoTSampleSwift.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A6B39BA91BF3A93600045F73 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0700; + ORGANIZATIONNAME = Amazon; + TargetAttributes = { + A6B39BB01BF3A93600045F73 = { + CreatedOnToolsVersion = 7.0.1; + }; + }; + }; + buildConfigurationList = A6B39BAC1BF3A93600045F73 /* Build configuration list for PBXProject "IoTSampleSwift" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A6B39BA81BF3A93600045F73; + productRefGroup = A6B39BB21BF3A93600045F73 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A6B39BB01BF3A93600045F73 /* IoTSampleSwift */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A6B39BAF1BF3A93600045F73 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A6B39BC11BF3A93600045F73 /* LaunchScreen.storyboard in Resources */, + A6B39BBE1BF3A93600045F73 /* Assets.xcassets in Resources */, + A6B39BBC1BF3A93600045F73 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4D1E2401B957BD82886A4683 /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 75F7F940938971BA0FD2C49C /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + DC1F7059CF8DC38C8DFA1A4A /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A6B39BAD1BF3A93600045F73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A6867C941BF530A700956B68 /* Constants.swift in Sources */, + A6B39BB91BF3A93600045F73 /* PublishViewController.swift in Sources */, + A62CEE5B1BF3B50800E9C895 /* SubscribeViewController.swift in Sources */, + A6B39BB51BF3A93600045F73 /* AppDelegate.swift in Sources */, + A6E263221C06870D0032B28D /* ConfigurationViewController.swift in Sources */, + A6CC2A291BFFCB6F00635393 /* IoTSampleTabBarController.swift in Sources */, + A6B39BB71BF3A93600045F73 /* ConnectionViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + A6B39BBA1BF3A93600045F73 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A6B39BBB1BF3A93600045F73 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + A6B39BBF1BF3A93600045F73 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A6B39BC01BF3A93600045F73 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A6B39BC31BF3A93600045F73 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A6B39BC41BF3A93600045F73 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + A6B39BC61BF3A93600045F73 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3B90C03514D3F9F7EDF1FF45 /* Pods.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = IoTSampleSwift/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "Amazon-Web-Services.IoTSampleSwift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "IoTSampleSwift/ObjectiveC-Bridging-Header.h"; + }; + name = Debug; + }; + A6B39BC71BF3A93600045F73 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 19CC868788E3FB2186476009 /* Pods.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = IoTSampleSwift/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "Amazon-Web-Services.IoTSampleSwift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "IoTSampleSwift/ObjectiveC-Bridging-Header.h"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A6B39BAC1BF3A93600045F73 /* Build configuration list for PBXProject "IoTSampleSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A6B39BC31BF3A93600045F73 /* Debug */, + A6B39BC41BF3A93600045F73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A6B39BC51BF3A93600045F73 /* Build configuration list for PBXNativeTarget "IoTSampleSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A6B39BC61BF3A93600045F73 /* Debug */, + A6B39BC71BF3A93600045F73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = A6B39BA91BF3A93600045F73 /* Project object */; +} diff --git a/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d802d8e --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/IoT-Sample/Swift/IoTSampleSwift.xcworkspace/contents.xcworkspacedata b/IoT-Sample/Swift/IoTSampleSwift.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..3469f910 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/IoT-Sample/Swift/IoTSampleSwift/AppDelegate.swift b/IoT-Sample/Swift/IoTSampleSwift/AppDelegate.swift new file mode 100644 index 00000000..593291e0 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/AppDelegate.swift @@ -0,0 +1,36 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + // Override point for customization after application launch. + let credentialProvider = AWSCognitoCredentialsProvider(regionType: AwsRegion, identityPoolId: CognitoIdentityPoolId) + + let configuration = AWSServiceConfiguration( + region: AwsRegion, + credentialsProvider: credentialProvider) + + AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration + + return true + } +} + diff --git a/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..36d2c80d --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/Contents.json b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/Contents.json new file mode 100644 index 00000000..33a74510 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/first.pdf b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/first.pdf new file mode 100644 index 00000000..47d911de Binary files /dev/null and b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/first.imageset/first.pdf differ diff --git a/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/Contents.json b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/Contents.json new file mode 100644 index 00000000..03bd9c92 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/second.pdf b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/second.pdf new file mode 100644 index 00000000..401614e2 Binary files /dev/null and b/IoT-Sample/Swift/IoTSampleSwift/Assets.xcassets/second.imageset/second.pdf differ diff --git a/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/LaunchScreen.storyboard b/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..432da737 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/Main.storyboard b/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/Main.storyboard new file mode 100644 index 00000000..bcbf0e7d --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Base.lproj/Main.storyboard @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IoT-Sample/Swift/IoTSampleSwift/ConfigurationViewController.swift b/IoT-Sample/Swift/IoTSampleSwift/ConfigurationViewController.swift new file mode 100644 index 00000000..947c92ed --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/ConfigurationViewController.swift @@ -0,0 +1,181 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit + +class ConfigurationViewController: UIViewController, UITextFieldDelegate { + @IBOutlet weak var deleteCertificateButton: UIButton! + @IBOutlet weak var topicTextField: UITextField! + + @IBAction func deleteCertificateButtonPressed(sender: AnyObject) { + let actionController: UIAlertController = UIAlertController( title: nil, message: nil, preferredStyle: .ActionSheet) + let cancelAction: UIAlertAction = UIAlertAction( title: "Cancel", style: .Cancel) { action -> Void in + } + actionController.addAction( cancelAction ) + + let okAction: UIAlertAction = UIAlertAction( title: "Delete", style: .Default) { action -> Void in + print( "deleting certificate...") + + // + // To delete the certificate: + // + // 1) Set the certificate's status to 'inactive' + // 2) Detach the policy from the certificate + // 3) Delete the certificate + // 4) Remove the keys and certificate from the keychain + // 5) Delete user defaults + // + let defaults = NSUserDefaults.standardUserDefaults() + let certificateId = defaults.stringForKey( "certificateId") + + if (certificateId != nil) + { + let iot = AWSIoT.defaultIoT() + + let updateCertificateRequest = AWSIoTUpdateCertificateRequest() + updateCertificateRequest.certificateId = certificateId + updateCertificateRequest.latestStatus = .Inactive + + iot.updateCertificate( updateCertificateRequest ).continueWithBlock { (task) -> AnyObject? in + + if let error = task.error { + print("failed: [\(error)]") + } + if let exception = task.exception { + print("failed: [\(exception)]") + } + print("result: [\(task.result)]") + if (task.exception == nil && task.error == nil) + { + // + // The certificate is now inactive; detach the policy from the + // certificate. + // + let certificateArn = defaults.stringForKey( "certificateArn") + let detachPolicyRequest = AWSIoTDetachPrincipalPolicyRequest() + detachPolicyRequest.principal = certificateArn + detachPolicyRequest.policyName = PolicyName + + iot.detachPrincipalPolicy(detachPolicyRequest).continueWithBlock { (task) -> AnyObject? in + if let error = task.error { + print("failed: [\(error)]") + } + if let exception = task.exception { + print("failed: [\(exception)]") + } + print("result: [\(task.result)]") + if (task.exception == nil && task.error == nil) + { + // + // The policy is now detached; delete the certificate + // + let deleteCertificateRequest = AWSIoTDeleteCertificateRequest() + deleteCertificateRequest.certificateId = certificateId + + iot.deleteCertificate(deleteCertificateRequest).continueWithBlock { (task) -> AnyObject? in + + if let error = task.error { + print("failed: [\(error)]") + } + if let exception = task.exception { + print("failed: [\(exception)]") + } + print("result: [\(task.result)]") + if (task.exception == nil && task.error == nil) + { + // + // The certificate has been deleted; now delete the keys + // and certificate from the keychain. + // + if (AWSIoTManager.deleteCertificate() != true) + { + print("error deleting certificate") + } + else + { + defaults.removeObjectForKey("certificateId") + defaults.removeObjectForKey("certificateArn") + dispatch_async( dispatch_get_main_queue() ) { + self.tabBarController?.selectedIndex = 0 + } + } + } + return nil + } + } + return nil + } + } + return nil + } + + } + else + { + print("certificate id == nil!") // shouldn't be possible + } + + } + actionController.addAction( okAction ) + self.presentViewController( actionController, animated: true, completion: nil ) + } + func textFieldShouldReturn(textField: UITextField) -> Bool { + topicTextField.resignFirstResponder() + return true + } + func textFieldDidEndEditing(textField: UITextField) { + topicTextField.text = textField.text + let defaults = NSUserDefaults.standardUserDefaults() + let tabBarViewController = tabBarController as! IoTSampleTabBarController + tabBarViewController.topic=textField.text! + defaults.setObject(textField.text, forKey:"sliderTopic") + } + override func viewDidLoad() { + super.viewDidLoad() + topicTextField.delegate = self + let defaults = NSUserDefaults.standardUserDefaults() + let certificateId = defaults.stringForKey( "certificateId") + let sliderTopic = defaults.stringForKey( "sliderTopic" ) + let tabBarViewController = tabBarController as! IoTSampleTabBarController + + if (certificateId == nil) + { + deleteCertificateButton.hidden=true + } + if (sliderTopic != nil) + { + tabBarViewController.topic=sliderTopic! + } + topicTextField.text = tabBarViewController.topic + } + override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + let defaults = NSUserDefaults.standardUserDefaults() + let certificateId = defaults.stringForKey( "certificateId") + + if (certificateId == nil) + { + deleteCertificateButton.hidden=true + } + else + { + deleteCertificateButton.hidden=false + } + } + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } +} \ No newline at end of file diff --git a/IoT-Sample/Swift/IoTSampleSwift/ConnectionViewController.swift b/IoT-Sample/Swift/IoTSampleSwift/ConnectionViewController.swift new file mode 100644 index 00000000..7e1ae06d --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/ConnectionViewController.swift @@ -0,0 +1,218 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit + +class ConnectionViewController: UIViewController, UITextViewDelegate { + + @IBOutlet weak var activityIndicatorView: UIActivityIndicatorView! + @IBOutlet weak var logTextView: UITextView! + + var connected = false; + var publishViewController : UIViewController!; + var subscribeViewController : UIViewController!; + var configurationViewController : UIViewController!; + + var iotDataManager: AWSIoTDataManager!; + var iotData: AWSIoTData! + var iotManager: AWSIoTManager!; + var iot: AWSIoT! + + @IBAction func connectButtonPressed(sender: UIButton) { + + let tabBarViewController = tabBarController as! IoTSampleTabBarController + + sender.enabled = false + + func mqttEventCallback( status: AWSIoTMQTTStatus ) + { + dispatch_async( dispatch_get_main_queue()) { + print("connection status = \(status.rawValue)") + switch(status) + { + case .Connecting: + tabBarViewController.mqttStatus = "Connecting..." + print( tabBarViewController.mqttStatus ) + self.logTextView.text = tabBarViewController.mqttStatus + + case .Connected: + tabBarViewController.mqttStatus = "Connected" + print( tabBarViewController.mqttStatus ) + sender.setTitle( "Disconnect", forState:.Normal) + self.activityIndicatorView.stopAnimating() + self.connected = true + sender.enabled = true + let uuid = NSUUID().UUIDString; + let defaults = NSUserDefaults.standardUserDefaults() + let certificateId = defaults.stringForKey( "certificateId") + + self.logTextView.text = "Using certificate:\n\(certificateId!)\n\n\nClient ID:\n\(uuid)" + + tabBarViewController.viewControllers = [ self, self.publishViewController, self.subscribeViewController ] + + + case .Disconnected: + tabBarViewController.mqttStatus = "Disconnected" + print( tabBarViewController.mqttStatus ) + self.activityIndicatorView.stopAnimating() + self.logTextView.text = nil + + case .ConnectionRefused: + tabBarViewController.mqttStatus = "Connection Refused" + print( tabBarViewController.mqttStatus ) + self.activityIndicatorView.stopAnimating() + self.logTextView.text = tabBarViewController.mqttStatus + + case .ConnectionError: + tabBarViewController.mqttStatus = "Connection Error" + print( tabBarViewController.mqttStatus ) + self.activityIndicatorView.stopAnimating() + self.logTextView.text = tabBarViewController.mqttStatus + + case .ProtocolError: + tabBarViewController.mqttStatus = "Protocol Error" + print( tabBarViewController.mqttStatus ) + self.activityIndicatorView.stopAnimating() + self.logTextView.text = tabBarViewController.mqttStatus + + default: + tabBarViewController.mqttStatus = "Unknown State" + print("unknown state: \(status.rawValue)") + self.activityIndicatorView.stopAnimating() + self.logTextView.text = tabBarViewController.mqttStatus + + } + NSNotificationCenter.defaultCenter().postNotificationName( "connectionStatusChanged", object: self ) + } + + } + + if (connected == false) + { + activityIndicatorView.startAnimating() + + let defaults = NSUserDefaults.standardUserDefaults() + var certificateId = defaults.stringForKey( "certificateId") + + if (certificateId == nil) + { + dispatch_async( dispatch_get_main_queue()) { + self.logTextView.text = "No certificate available, creating one..." + } + print ("no certificate found") + // + // Now create and store the certificate ID in NSUserDefaults + // + let csrDictionary = [ "commonName":CertificateSigningRequestCommonName, "countryName":CertificateSigningRequestCountryName, "organizationName":CertificateSigningRequestOrganizationName, "organizationalUnitName":CertificateSigningRequestOrganizationalUnitName ] + + self.iotManager.createKeysAndCertificateFromCsr(csrDictionary, callback: { (response ) -> Void in + defaults.setObject(response.certificateId, forKey:"certificateId") + defaults.setObject(response.certificateArn, forKey:"certificateArn") + certificateId = response.certificateId + print("response: [\(response)]") + let uuid = NSUUID().UUIDString; + + let attachPrincipalPolicyRequest = AWSIoTAttachPrincipalPolicyRequest() + attachPrincipalPolicyRequest.policyName = PolicyName + attachPrincipalPolicyRequest.principal = response.certificateArn + // + // Attach the policy to the certificate + // + self.iot.attachPrincipalPolicy(attachPrincipalPolicyRequest).continueWithBlock { (task) -> AnyObject? in + if let error = task.error { + print("failed: [\(error)]") + } + if let exception = task.exception { + print("failed: [\(exception)]") + } + print("result: [\(task.result)]") + // + // Connect to the AWS IoT platform + // + if (task.exception == nil && task.error == nil) + { + let delayTime = dispatch_time( DISPATCH_TIME_NOW, Int64(2*Double(NSEC_PER_SEC))) + dispatch_after( delayTime, dispatch_get_main_queue()) { + self.logTextView.text = "Using certificate: \(certificateId!)" + self.iotDataManager.connectWithClientId( uuid, cleanSession:true, certificateId:certificateId,statusCallback: mqttEventCallback) + } + } + return nil + } + } ) + } + else + { + let uuid = NSUUID().UUIDString; + + // + // Connect to the AWS IoT service + // + iotDataManager.connectWithClientId( uuid, cleanSession:true, certificateId:certificateId, statusCallback: mqttEventCallback) + } + } + else + { + activityIndicatorView.startAnimating() + logTextView.text = "Disconnecting..." + + dispatch_async( dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0) ){ + self.iotDataManager.disconnect(); + dispatch_async( dispatch_get_main_queue() ) { + self.activityIndicatorView.stopAnimating() + self.connected = false + sender.setTitle( "Connect", forState:.Normal) + sender.enabled = true + tabBarViewController.viewControllers = [ self, self.configurationViewController ] + } + } + } + } + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + + let tabBarViewController = tabBarController as! IoTSampleTabBarController + publishViewController = tabBarViewController.viewControllers![1] + subscribeViewController = tabBarViewController.viewControllers![2] + configurationViewController = tabBarViewController.viewControllers![3] + + tabBarViewController.viewControllers = [ self, configurationViewController ] + logTextView.resignFirstResponder() + + // Init IOT + // + // Set up Cognito + // + let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AwsRegion, identityPoolId: CognitoIdentityPoolId) + let configuration = AWSServiceConfiguration(region: AwsRegion, credentialsProvider: credentialsProvider) + + AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration + + iotManager = AWSIoTManager.defaultIoTManager() + iot = AWSIoT.defaultIoT() + + iotDataManager = AWSIoTDataManager.defaultIoTDataManager() + iotData = AWSIoTData.defaultIoTData() + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } +} + diff --git a/IoT-Sample/Swift/IoTSampleSwift/Constants.swift b/IoT-Sample/Swift/IoTSampleSwift/Constants.swift new file mode 100644 index 00000000..b636757f --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Constants.swift @@ -0,0 +1,25 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import Foundation + +//WARNING: To run this sample correctly, you must set the following constants. +let AwsRegion = AWSRegionType.Unknown // e.g. AWSRegionType.USEast1 +let CognitoIdentityPoolId = "YourCognitoIdentityPoolId" +let CertificateSigningRequestCommonName = "IoTSampleSwift Application" +let CertificateSigningRequestCountryName = "Your Country" +let CertificateSigningRequestOrganizationName = "Your Organization" +let CertificateSigningRequestOrganizationalUnitName = "Your Organizational Unit" +let PolicyName = "YourPolicyName" diff --git a/IoT-Sample/Swift/IoTSampleSwift/Info.plist b/IoT-Sample/Swift/IoTSampleSwift/Info.plist new file mode 100644 index 00000000..fd1ab7c3 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/Info.plist @@ -0,0 +1,57 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/IoT-Sample/Swift/IoTSampleSwift/IoTSampleTabBarController.swift b/IoT-Sample/Swift/IoTSampleSwift/IoTSampleTabBarController.swift new file mode 100644 index 00000000..04b8ceb6 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/IoTSampleTabBarController.swift @@ -0,0 +1,22 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit + +class IoTSampleTabBarController: UITabBarController { + + var mqttStatus: String = "Disconnected" + var topic: String = "slider" +} \ No newline at end of file diff --git a/IoT-Sample/Swift/IoTSampleSwift/ObjectiveC-Bridging-Header.h b/IoT-Sample/Swift/IoTSampleSwift/ObjectiveC-Bridging-Header.h new file mode 100644 index 00000000..7f91215f --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/ObjectiveC-Bridging-Header.h @@ -0,0 +1,6 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import diff --git a/IoT-Sample/Swift/IoTSampleSwift/PublishViewController.swift b/IoT-Sample/Swift/IoTSampleSwift/PublishViewController.swift new file mode 100644 index 00000000..8e7825a4 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/PublishViewController.swift @@ -0,0 +1,38 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit + +class PublishViewController: UIViewController { + + @IBOutlet weak var publishSlider: UISlider! + + override func viewDidLoad() { + super.viewDidLoad() + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + @IBAction func sliderValueChanged(sender: UISlider) { + print("\(sender.value)") + + let iotDataManager = AWSIoTDataManager.defaultIoTDataManager() + let tabBarViewController = tabBarController as! IoTSampleTabBarController + + iotDataManager.publishString("\(sender.value)", onTopic:tabBarViewController.topic) + } +} \ No newline at end of file diff --git a/IoT-Sample/Swift/IoTSampleSwift/SubscribeViewController.swift b/IoT-Sample/Swift/IoTSampleSwift/SubscribeViewController.swift new file mode 100644 index 00000000..53f031e7 --- /dev/null +++ b/IoT-Sample/Swift/IoTSampleSwift/SubscribeViewController.swift @@ -0,0 +1,55 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit + +class SubscribeViewController: UIViewController { + + @IBOutlet weak var subscribeSlider: UISlider! + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view, typically from a nib. + subscribeSlider.enabled = false + } + + override func viewWillAppear(animated: Bool) { + let iotDataManager = AWSIoTDataManager.defaultIoTDataManager() + let tabBarViewController = tabBarController as! IoTSampleTabBarController + + iotDataManager.subscribeToTopic(tabBarViewController.topic, qos: 0, messageCallback: { + (payload) ->Void in + let stringValue = NSString(data: payload, encoding: NSUTF8StringEncoding)! + + print("received: \(stringValue)") + dispatch_async(dispatch_get_main_queue()) { + self.subscribeSlider.value = stringValue.floatValue + } + } ) + } + + override func viewWillDisappear(animated: Bool) { + let iotDataManager = AWSIoTDataManager.defaultIoTDataManager() + let tabBarViewController = tabBarController as! IoTSampleTabBarController + iotDataManager.unsubscribeTopic(tabBarViewController.topic) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } +} + diff --git a/IoT-Sample/Swift/Podfile b/IoT-Sample/Swift/Podfile new file mode 100755 index 00000000..93686441 --- /dev/null +++ b/IoT-Sample/Swift/Podfile @@ -0,0 +1,5 @@ +source 'https://github.com/CocoaPods/Specs.git' + +platform :ios, '8.0' + +pod 'AWSIoT', '~> 2.3.2' diff --git a/IoT-Sample/Swift/README.md b/IoT-Sample/Swift/README.md new file mode 100644 index 00000000..34eeeb5a --- /dev/null +++ b/IoT-Sample/Swift/README.md @@ -0,0 +1,60 @@ +# The Amazon IoT Sample + +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. + +## Requirements + +* Xcode 7 and later +* iOS 8 and later + +## Using the Sample + +1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods: + + sudo gem install cocoapods + pod setup + +1. To install the AWS Mobile SDK for iOS, simply add the following line to your **Podfile**: + + pod 'AWSIoT' + + Then run the following command: + + pod install + +1. In the [Amazon Cognito console](https://console.aws.amazon.com/cognito/), use Amazon Cognito to create a new identity pool. Obtain the `PoolID` constant. Make sure the [role](https://console.aws.amazon.com/iam/home?region=us-east-1#roles) has full permissions to access the AWS IoT APIs, as shown in this example: + +```sh +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iot:*" + ], + "Resource": "*" + } + ] +} +``` + +1. In the [Amazon AWS IoT console](https://console.aws.amazon.com/iot/), create a policy with full permissions to access AWS IoT as shown in this example. Select 'Create a Policy', fill in the 'Name' field, set 'Action' to 'iot:\*', set 'Resource' to '\*', and then click 'Create'. + +1. Open `IoTSampleSwift.xcworkspace`. + +1. Open `Constants.swift` and update the following lines with the appropriate constants: + +```c +let AwsRegion = AWSRegionType.Unknown +let CognitoIdentityPoolId = "YourCognitoIdentityPoolId" +let CertificateSigningRequestCommonName = "IoTSampleSwift Application" +let CertificateSigningRequestCountryName = "Your Country" +let CertificateSigningRequestOrganizationName = "Your Organization" +let CertificateSigningRequestOrganizationalUnitName = "Your Organizational Unit" +let PolicyName = "YourPolicyName" +``` + +1. Build and run the sample app. + +1. 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. You can use another instance of this application so that one instance publishes while the other subscribes, or you can use another MQTT client such as [mosquitto](http://mosquitto.org/) to interact with your application. diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcodeproj/project.pbxproj b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8cbac2ff --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcodeproj/project.pbxproj @@ -0,0 +1,382 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 35C3CD403632B80E765AADE4 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 57A0238D25B5B3B30E0A29D9 /* Pods.framework */; }; + A625DEC11C0F753C00DB1463 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A625DEC01C0F753C00DB1463 /* AppDelegate.swift */; }; + A625DEC31C0F753C00DB1463 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A625DEC21C0F753C00DB1463 /* ViewController.swift */; }; + A625DEC61C0F753C00DB1463 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A625DEC41C0F753C00DB1463 /* Main.storyboard */; }; + A625DEC81C0F753C00DB1463 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A625DEC71C0F753C00DB1463 /* Assets.xcassets */; }; + A625DECB1C0F753C00DB1463 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A625DEC91C0F753C00DB1463 /* LaunchScreen.storyboard */; }; + A6A007D01C0F9F3E00073985 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6A007CF1C0F9F3E00073985 /* Constants.swift */; settings = {ASSET_TAGS = (); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1292D3607FA1249F5E28CAC8 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + 57A0238D25B5B3B30E0A29D9 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A625DEBD1C0F753C00DB1463 /* IoTTemperatureControlSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IoTTemperatureControlSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A625DEC01C0F753C00DB1463 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A625DEC21C0F753C00DB1463 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + A625DEC51C0F753C00DB1463 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + A625DEC71C0F753C00DB1463 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + A625DECA1C0F753C00DB1463 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + A625DECC1C0F753C00DB1463 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A6A007CF1C0F9F3E00073985 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + B9F3D667F8E3307DD81B1B14 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A625DEBA1C0F753C00DB1463 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 35C3CD403632B80E765AADE4 /* Pods.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6D22B6498074B09E7BF9A704 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 57A0238D25B5B3B30E0A29D9 /* Pods.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 89C0F3D9C6E4A63A6E8C9C84 /* Pods */ = { + isa = PBXGroup; + children = ( + B9F3D667F8E3307DD81B1B14 /* Pods.debug.xcconfig */, + 1292D3607FA1249F5E28CAC8 /* Pods.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + A625DEB41C0F753C00DB1463 = { + isa = PBXGroup; + children = ( + A625DEBF1C0F753C00DB1463 /* IoTTemperatureControlSample */, + A625DEBE1C0F753C00DB1463 /* Products */, + 89C0F3D9C6E4A63A6E8C9C84 /* Pods */, + 6D22B6498074B09E7BF9A704 /* Frameworks */, + ); + sourceTree = ""; + }; + A625DEBE1C0F753C00DB1463 /* Products */ = { + isa = PBXGroup; + children = ( + A625DEBD1C0F753C00DB1463 /* IoTTemperatureControlSample.app */, + ); + name = Products; + sourceTree = ""; + }; + A625DEBF1C0F753C00DB1463 /* IoTTemperatureControlSample */ = { + isa = PBXGroup; + children = ( + A6A007CF1C0F9F3E00073985 /* Constants.swift */, + A625DEC01C0F753C00DB1463 /* AppDelegate.swift */, + A625DEC21C0F753C00DB1463 /* ViewController.swift */, + A625DEC41C0F753C00DB1463 /* Main.storyboard */, + A625DEC71C0F753C00DB1463 /* Assets.xcassets */, + A625DEC91C0F753C00DB1463 /* LaunchScreen.storyboard */, + A6A007CD1C0F760100073985 /* Internal */, + ); + path = IoTTemperatureControlSample; + sourceTree = ""; + }; + A6A007CD1C0F760100073985 /* Internal */ = { + isa = PBXGroup; + children = ( + A625DECC1C0F753C00DB1463 /* Info.plist */, + ); + name = Internal; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A625DEBC1C0F753C00DB1463 /* IoTTemperatureControlSample */ = { + isa = PBXNativeTarget; + buildConfigurationList = A625DECF1C0F753C00DB1463 /* Build configuration list for PBXNativeTarget "IoTTemperatureControlSample" */; + buildPhases = ( + 11CBFDC0B3C1CE0BAD86BB7D /* Check Pods Manifest.lock */, + A625DEB91C0F753C00DB1463 /* Sources */, + A625DEBA1C0F753C00DB1463 /* Frameworks */, + A625DEBB1C0F753C00DB1463 /* Resources */, + DAD179729B23559785C71E09 /* Copy Pods Resources */, + 1F530B41058F573EA1E1DF7B /* Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IoTTemperatureControlSample; + productName = IoTTemperatureControlSample; + productReference = A625DEBD1C0F753C00DB1463 /* IoTTemperatureControlSample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A625DEB51C0F753C00DB1463 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0700; + ORGANIZATIONNAME = Amazon; + TargetAttributes = { + A625DEBC1C0F753C00DB1463 = { + CreatedOnToolsVersion = 7.0.1; + }; + }; + }; + buildConfigurationList = A625DEB81C0F753C00DB1463 /* Build configuration list for PBXProject "IoTTemperatureControlSample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A625DEB41C0F753C00DB1463; + productRefGroup = A625DEBE1C0F753C00DB1463 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A625DEBC1C0F753C00DB1463 /* IoTTemperatureControlSample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A625DEBB1C0F753C00DB1463 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A625DECB1C0F753C00DB1463 /* LaunchScreen.storyboard in Resources */, + A625DEC81C0F753C00DB1463 /* Assets.xcassets in Resources */, + A625DEC61C0F753C00DB1463 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 11CBFDC0B3C1CE0BAD86BB7D /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 1F530B41058F573EA1E1DF7B /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + DAD179729B23559785C71E09 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A625DEB91C0F753C00DB1463 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A625DEC31C0F753C00DB1463 /* ViewController.swift in Sources */, + A625DEC11C0F753C00DB1463 /* AppDelegate.swift in Sources */, + A6A007D01C0F9F3E00073985 /* Constants.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + A625DEC41C0F753C00DB1463 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A625DEC51C0F753C00DB1463 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + A625DEC91C0F753C00DB1463 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A625DECA1C0F753C00DB1463 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A625DECD1C0F753C00DB1463 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A625DECE1C0F753C00DB1463 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + A625DED01C0F753C00DB1463 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B9F3D667F8E3307DD81B1B14 /* Pods.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = IoTTemperatureControlSample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "Amazon-Web-Services.IoTTemperatureControlSample"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + A625DED11C0F753C00DB1463 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1292D3607FA1249F5E28CAC8 /* Pods.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = IoTTemperatureControlSample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "Amazon-Web-Services.IoTTemperatureControlSample"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A625DEB81C0F753C00DB1463 /* Build configuration list for PBXProject "IoTTemperatureControlSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A625DECD1C0F753C00DB1463 /* Debug */, + A625DECE1C0F753C00DB1463 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A625DECF1C0F753C00DB1463 /* Build configuration list for PBXNativeTarget "IoTTemperatureControlSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A625DED01C0F753C00DB1463 /* Debug */, + A625DED11C0F753C00DB1463 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = A625DEB51C0F753C00DB1463 /* Project object */; +} diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..c78ddd3d --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcworkspace/contents.xcworkspacedata b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..d9b5e85d --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/AppDelegate.swift b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/AppDelegate.swift new file mode 100644 index 00000000..ddb24ac5 --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/AppDelegate.swift @@ -0,0 +1,37 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit +import AWSCore + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + // + // Set up Cognito + // + let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AwsRegion, identityPoolId: CognitoIdentityPoolId) + let configuration = AWSServiceConfiguration(region: AwsRegion, credentialsProvider: credentialsProvider) + AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration + + return true + } + +} + diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Assets.xcassets/AppIcon.appiconset/Contents.json b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..36d2c80d --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Base.lproj/LaunchScreen.storyboard b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..2e721e18 --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Base.lproj/Main.storyboard b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Base.lproj/Main.storyboard new file mode 100644 index 00000000..3ec2a30b --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Base.lproj/Main.storyboard @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Constants.swift b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Constants.swift new file mode 100644 index 00000000..2f18bdc1 --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Constants.swift @@ -0,0 +1,21 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import Foundation +import AWSCore + +//WARNING: To run this sample correctly, you must set the following constants. +let AwsRegion = AWSRegionType.Unknown // e.g. AWSRegionType.USEast1 +let CognitoIdentityPoolId = "YourCognitoIdentityPoolId" \ No newline at end of file diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Info.plist b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Info.plist new file mode 100644 index 00000000..40c6215d --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/ViewController.swift b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/ViewController.swift new file mode 100644 index 00000000..37d1647d --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/IoTTemperatureControlSample/ViewController.swift @@ -0,0 +1,207 @@ +/* +* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +import UIKit +import AWSCore +import AWSIoT +import SwiftyJSON + +// +// These values must match the values from the temperature-control example +// in the aws-iot-device-sdk.js package (https://github.com/aws/aws-iot-device-sdk-js) +// +let statusThingName="TemperatureStatus" +let controlThingName="TemperatureControl" + +class ViewController: UIViewController { + @IBOutlet weak var setpointLabel: UILabel! + @IBOutlet weak var interiorLabel: UILabel! + @IBOutlet weak var exteriorLabel: UILabel! + @IBOutlet weak var statusSwitch: UISwitch! + @IBOutlet weak var setpointStepper: UIStepper! + + var interiorTemperature: Int = 70; + var exteriorTemperature: Int = 45; + var currentRunningState: String="stopped"; + var currentlyEnabled: Bool = true; + var currentSetpoint: Int = 68; + weak var pollingTimer: NSTimer?; + + func updateThingShadow( thingName: String, jsonData: JSON ) + { + let updateThingShadowRequest = AWSIoTDataUpdateThingShadowRequest() + updateThingShadowRequest.thingName = thingName + do { + let tmpVal = try jsonData.rawData() + + let IoTData = AWSIoTData.defaultIoTData() + + updateThingShadowRequest.payload = tmpVal + IoTData.updateThingShadow(updateThingShadowRequest).continueWithBlock { (task) -> AnyObject? in + if let error = task.error { + print("failed: [\(error)]") + } + if let exception = task.exception { + print("failed: [\(exception)]") + } + if (task.error == nil && task.exception == nil) { + // let result = task.result! + // let json = JSON(data: result.payload as NSData!) + // + // The latest state of the device shadow is in 'json' + // + } + // + // Re-enable polling + // + dispatch_async( dispatch_get_main_queue()) { + if (self.pollingTimer == nil) { + self.pollingTimer = NSTimer.scheduledTimerWithTimeInterval( 0.5, target: self, selector: "getThingStates", userInfo: nil, repeats: true ) + } + } + return nil + } + } + catch { + print("couldn't convert to raw") + } + } + + @IBAction func statusSwitchChanged(sender: UISwitch) { + // + // Initialize the control JSON object + // + let controlJson = JSON(["state": ["desired": [ "setPoint": currentSetpoint, "enabled": sender.on]]]) + // + // Disable polling while waiting on a response from updating the thing shadow + // + if (self.pollingTimer != nil) { + self.pollingTimer?.invalidate(); + } + updateThingShadow( controlThingName, jsonData: controlJson ) + } + + @IBAction func setpointStepperTapped(sender: UIStepper) { + // + // Initialize the control JSON object + // + let controlJson = JSON(["state": ["desired": [ "setPoint": Int(sender.value), "enabled": currentlyEnabled]]]) + // + // Disable polling while waiting on a response from updating the thing shadow + // + if (self.pollingTimer != nil) { + self.pollingTimer?.invalidate(); + } + currentSetpoint = Int(setpointStepper.value) + setpointLabel.text = String(currentSetpoint) + updateThingShadow( controlThingName, jsonData: controlJson ) + } + + func getThingState( thingName: String, completion: (String, JSON) -> Void ) + { + let IoTData = AWSIoTData.defaultIoTData() + + let getThingShadowRequest = AWSIoTDataGetThingShadowRequest() + getThingShadowRequest.thingName = thingName + IoTData.getThingShadow(getThingShadowRequest).continueWithBlock { (task) -> AnyObject? in + if let error = task.error { + print("failed: [\(error)]") + } + if let exception = task.exception { + print("failed: [\(exception)]") + } + if (task.error == nil && task.exception == nil) { + dispatch_async( dispatch_get_main_queue()) { + let result = task.result! + let json = JSON(data: result.payload as NSData!) + completion( thingName, json ) + } + } + return nil + } + } + func statusThingShadowCallback( thingName: String, json: JSON ) -> Void { +// print("\(thingName): \(json)") + if let tmpIntTemp = json["state"]["desired"]["intTemp"].int { + interiorTemperature = tmpIntTemp + interiorLabel.text = String(interiorTemperature) + } + if let tmpExtTemp = json["state"]["desired"]["extTemp"].int { + exteriorTemperature = tmpExtTemp + exteriorLabel.text = String(exteriorTemperature) + } + if let tmpState = json["state"]["desired"]["curState"].string { + currentRunningState = tmpState + switch(currentRunningState) + { + case "stopped": + interiorLabel.textColor = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 1.0) + case "heating": + interiorLabel.textColor = UIColor(red:1.0, green: 0.0, blue: 0.0, alpha: 1.0) + case "cooling": + interiorLabel.textColor = UIColor(red:0.0, green: 0.0, blue: 1.0, alpha: 1.0) + default: + interiorLabel.textColor = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 1.0) + } + } + } + func controlThingShadowCallback( thingName: String, json: JSON ) -> Void { +// print("\(thingName): \(json)") + if let tmpSetpoint = json["state"]["desired"]["setPoint"].int { + currentSetpoint = tmpSetpoint + setpointStepper.value=Double(currentSetpoint) + setpointLabel.text = String(currentSetpoint) + } + if let tmpEnabled = json["state"]["desired"]["enabled"].bool { + currentlyEnabled = tmpEnabled + statusSwitch.on = currentlyEnabled + } + } + func getThingStates() { + getThingState(statusThingName, completion: statusThingShadowCallback) + getThingState(controlThingName, completion: controlThingShadowCallback) + } + + override func viewDidLoad() { + super.viewDidLoad() + // + // Initialize the setpoint stepper + // + setpointStepper.wraps=false + setpointStepper.maximumValue=90 + setpointStepper.minimumValue=50 + setpointStepper.value=70 + // + // Initialize the temperature and setpoint labels + // + interiorLabel.text="60" + exteriorLabel.text="45" + setpointLabel.text=setpointStepper.value.description + // + // Initialize the status switch + // + statusSwitch.on=true + + pollingTimer = NSTimer.scheduledTimerWithTimeInterval( 0.5, target: self, selector: "getThingStates", userInfo: nil, repeats: true ) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} + diff --git a/IoTTemperatureControl-Sample/Swift/Podfile b/IoTTemperatureControl-Sample/Swift/Podfile new file mode 100755 index 00000000..cbc2e492 --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' + +use_frameworks! +platform :ios, '8.0' + +pod 'AWSIoT', '~> 2.3.2' +pod 'SwiftyJSON' diff --git a/IoTTemperatureControl-Sample/Swift/README.md b/IoTTemperatureControl-Sample/Swift/README.md new file mode 100644 index 00000000..5e7af183 --- /dev/null +++ b/IoTTemperatureControl-Sample/Swift/README.md @@ -0,0 +1,57 @@ +# The Amazon IoT Temperature Control Sample + +This sample demonstrates use of the AWS IoT APIs to interact with device shadows. It works in conjunction with the Temperature Control Example Program in the [AWS IoT JavaScript SDK for Embedded Devices](https://github.com/aws/aws-iot-device-sdk-js). + +## Requirements + +* Xcode 7 and later +* iOS 8 and later + +## Using the Sample + +1. The AWS Mobile SDK for iOS is available through [CocoaPods](http://cocoapods.org). If you have not installed CocoaPods, install CocoaPods: + + sudo gem install cocoapods + pod setup + +1. To install the AWS Mobile SDK for iOS, simply add the following line to your **Podfile**: + + pod 'AWSIoT' + + Then run the following command: + + pod install + +1. In the [Amazon Cognito console](https://console.aws.amazon.com/cognito/), use Amazon Cognito to create a new identity pool. Obtain the `PoolID` constant. Make sure the [role](https://console.aws.amazon.com/iam/home?region=us-east-1#roles) has full permissions to access the AWS IoT APIs, as shown in this example: + +```sh +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iot:*" + ], + "Resource": "*" + } + ] +} +``` + +1. Open `IoTTemperatureControlSample.xcworkspace`. + +1. Open `Constants.swift` and update the following lines with the appropriate constants: + +```c +let AwsRegion = AWSRegionType.Unknown +let CognitoIdentityPoolId = "YourCognitoIdentityPoolId" +``` + +1. Install the [AWS IoT JavaScript SDK for Embedded Devices](https://github.com/aws/aws-iot-device-sdk-js). + +1. Follow the instructions in the AWS IoT JavaScript SDK for Embedded Devices to install depenedencies for the temperature-control example application. + +1. Start the AWS IoT JavaScript SDK for Embedded Devices temperature-control example application using '--test-mode=2' to simulate a temperature control device. + +1. Build and run the sample app. diff --git a/README.md b/README.md index f080b3f2..98869bc1 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,26 @@ This sample demonstrates how to set up Amazon SNS Mobile Push and record events * [Amazon Mobile Analytics](http://aws.amazon.com/mobileanalytics/) * [Amazon Cognito Identity](http://aws.amazon.com/cognito/) +###IoT Sample ([Swift](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/IoT-Sample/Swift/)) + +This sample demonstrates how to publish and subscribe to data using AWS IoT. + +####AWS Services Demonstrated: + +* [Amazon AWS IoT](http://aws.amazon.com/iot/) +* [Amazon Cognito Identity](http://aws.amazon.com/cognito/) + +###IoT Temperature Control Sample ([Swift](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/IoTTemperatureControl-Sample/Swift/)) + +This sample demonstrates accessing device shadows using Cognito authentication; it works in conjunction with the Temperature Control Example Program in the [AWS IoT JavaScript SDK for Embedded Devices](https://github.com/aws/aws-iot-device-sdk-js). + +####AWS Services Demonstrated: + +* [Amazon AWS IoT](http://aws.amazon.com/iot/) +* [Amazon Cognito Identity](http://aws.amazon.com/cognito/) + ###Sample Apps for Version 1 SDK Version 1 of the AWS Mobile SDK for iOS is deprecated as of September 29, 2014. If you are building new apps, we recommend you use Version 2. -To find the samples for Version 1 of the AWS Mobile SDK for iOS, select the [v1 branch](https://github.com/awslabs/aws-sdk-ios-samples/tree/v1). \ No newline at end of file +To find the samples for Version 1 of the AWS Mobile SDK for iOS, select the [v1 branch](https://github.com/awslabs/aws-sdk-ios-samples/tree/v1).