Last active
May 2, 2019 01:37
-
-
Save chandraf22/0f1723ca83edc13c06238a807931a224 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AWSMqtt.swift | |
// AWSIOTMQTT | |
// | |
// Created by Chandrachudh on 22/08/18. | |
// Copyright © 2018 Facebook. All rights reserved. | |
// | |
import Foundation | |
@objc(AWSMqtt)//To make it a Objective C Class | |
class AWSMqtt: RCTEventEmitter {//This class needs some features provided by react native library | |
private var connected = false; | |
private var iotDataManager: AWSIoTDataManager!; | |
private var iotManager: AWSIoTManager!; | |
private var iot: AWSIoT! | |
private var allSubscribedTopics = [String]() | |
override static func requiresMainQueueSetup() -> Bool {//This code is needed. don't remove | |
return true | |
} | |
override func supportedEvents() -> [String]! {//These are the name of events that the react native will receive | |
return["connectionStatus","mesage"] | |
} | |
//Setup AWSIOT | |
func setupAAWSMQTT() { | |
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegion, identityPoolId: CognitoIdentityPoolId) | |
let iotEndPoint = AWSEndpoint(urlString: IOT_ENDPOINT) | |
let iotConfiguration = AWSServiceConfiguration(region: AWSRegion, credentialsProvider: credentialsProvider) | |
let iotDataConfiguration = AWSServiceConfiguration(region: AWSRegion, | |
endpoint: iotEndPoint, | |
credentialsProvider: credentialsProvider) | |
AWSServiceManager.default().defaultServiceConfiguration = iotConfiguration | |
iotManager = AWSIoTManager.default() | |
iot = AWSIoT.default() | |
AWSIoTDataManager.register(with: iotDataConfiguration!, forKey: ASWIoTDataManager) | |
iotDataManager = AWSIoTDataManager(forKey: ASWIoTDataManager) | |
allSubscribedTopics.removeAll() | |
} | |
//Connect to AWSIOT using the ceritificate | |
func connectToAWSMQTT() { | |
func mqttEventCallback( _ status: AWSIoTMQTTStatus ) | |
{ | |
DispatchQueue.main.async { | |
print("connection status = \(status.rawValue)") | |
self.sendEvent(withName: "connectionStatus", body: ["status":status.rawValue]) | |
switch(status) | |
{ | |
case .connecting: | |
print("Connecting...") | |
case .connected: | |
print("Connected") | |
self.connected = true | |
case .disconnected: | |
print("Disconnected") | |
case .connectionRefused: | |
print("Connection Refused") | |
case .connectionError: | |
print("Connection Error") | |
case .protocolError: | |
print("Protocol Error") | |
default: | |
print("unknown state: \(status.rawValue)") | |
} | |
NotificationCenter.default.post( name: Notification.Name(rawValue: "connectionStatusChanged"), object: self ) | |
} | |
} | |
if (connected == false) | |
{ | |
let defaults = UserDefaults.standard | |
var certificateId = defaults.string( forKey: "certificateId") | |
if (certificateId == nil) | |
{ | |
let uuid = UUID().uuidString; | |
certificateId = defaults.string( forKey: "certificateId") | |
if (certificateId == nil) { | |
// Now create and store the certificate ID in NSUserDefaults | |
let csrDictionary = [ "commonName":CertificateSigningRequestCommonName, "countryName":CertificateSigningRequestCountryName, "organizationName":CertificateSigningRequestOrganizationName, "organizationalUnitName":CertificateSigningRequestOrganizationalUnitName] | |
self.iotManager.createKeysAndCertificate(fromCsr: csrDictionary, callback: { (response ) -> Void in | |
if (response != nil) | |
{ | |
defaults.set(response?.certificateId, forKey:"certificateId") | |
defaults.set(response?.certificateArn, forKey:"certificateArn") | |
certificateId = response?.certificateId | |
print("response: [\(String(describing: response))]") | |
let attachPrincipalPolicyRequest = AWSIoTAttachPrincipalPolicyRequest() | |
attachPrincipalPolicyRequest?.policyName = PolicyName | |
attachPrincipalPolicyRequest?.principal = response?.certificateArn | |
// Attach the policy to the certificate | |
self.iot.attachPrincipalPolicy(attachPrincipalPolicyRequest!).continueWith (block: { (task) -> AnyObject? in | |
if let error = task.error { | |
print("failed: [\(error)]") | |
} | |
print("result: [\(String(describing: task.result))]") | |
// Connect to the AWS IoT platform | |
if (task.error == nil) | |
{ | |
DispatchQueue.main.asyncAfter(deadline: .now()+2, execute: { | |
self.iotDataManager.connect( withClientId: uuid, cleanSession:true, certificateId:certificateId!, statusCallback: mqttEventCallback) | |
}) | |
} | |
return nil | |
}) | |
} | |
else | |
{ | |
DispatchQueue.main.async { | |
print("Unable to create keys and/or certificate, check values in Constants.swift") | |
} | |
} | |
} ) | |
} | |
} | |
else | |
{ | |
let uuid = UUID().uuidString; | |
DispatchQueue.main.async { | |
// Connect to the AWS IoT service | |
self.iotDataManager.connect( withClientId: uuid, cleanSession:true, certificateId:certificateId!, statusCallback: mqttEventCallback) | |
} | |
} | |
} | |
else | |
{ | |
print("Force Disconnecting...") | |
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { | |
self.iotDataManager.disconnect(); | |
DispatchQueue.main.async { | |
self.connected = false | |
} | |
} | |
} | |
} | |
//Publish a message to AWSIOT channel/topic | |
@objc func publishToAWSMQTT(_ topic:String, message:String) { | |
iotDataManager.publishString(message, onTopic:topic, qoS:.messageDeliveryAttemptedAtMostOnce) | |
} | |
//Subscribe to a channel/topic | |
@objc func subscribeFromAwsMqtt(_ topic:String) { | |
if (allSubscribedTopics.contains(topic) == false) { | |
allSubscribedTopics.append(topic) | |
} | |
iotDataManager.subscribe(toTopic: topic, qoS: .messageDeliveryAttemptedAtMostOnce, messageCallback: { (payload) ->Void in | |
let stringValue = NSString(data: payload, encoding: String.Encoding.utf8.rawValue)! | |
self.sendEvent(withName: "message", body: ["message":stringValue]) | |
} ) | |
} | |
//Unsubscribe to a specific topic/channel | |
@objc func unsubscribeTopic(_ topic:String) { | |
iotDataManager.unsubscribeTopic(topic) | |
if let index = allSubscribedTopics.index(of: topic) { | |
allSubscribedTopics.remove(at: index) | |
} | |
} | |
//unsubscribe to all topics/channels | |
@objc func unsubscribeAllTopics() { | |
for topic in allSubscribedTopics { | |
iotDataManager.unsubscribeTopic(topic) | |
} | |
allSubscribedTopics.removeAll() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tried to comment on your Medium article related to this code, but the commenting system does not seem to work on my computer.
I started off integrating Android, and that worked well. With this code file however I've encountered an issue on line 44 and 45. The forKey value is ASWIoTDataManager. xCode simply states that this is an unresolved identifier. I assumed it was a simple spelling mistake. I changed it to AWSIoTDataManager, but then xCode state "Cannot convert value of type 'AWSIoTDataManager.Type' to expected argument type 'String'". Do you happen to know what the issue might be? Unfortunately I'm not very experienced with iOS dev, so I'm having trouble figuring this out on my own.