Skip to content

Instantly share code, notes, and snippets.

@chandraf22
Last active May 2, 2019 01:37
Show Gist options
  • Save chandraf22/0f1723ca83edc13c06238a807931a224 to your computer and use it in GitHub Desktop.
Save chandraf22/0f1723ca83edc13c06238a807931a224 to your computer and use it in GitHub Desktop.
//
// 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()
}
}
@alehel
Copy link

alehel commented Mar 22, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment