From 92df829e3a71eb63ac45a51a9b5c04f45b880b78 Mon Sep 17 00:00:00 2001 From: Josip Cavar Date: Thu, 1 Feb 2018 13:21:06 +0100 Subject: [PATCH] Remove unnecessary APIs and provide completion handler --- .../MQTTClient/ForegroundReconnection.m | 2 +- MQTTClient/MQTTClient/MQTTSessionManager.h | 134 +------------- MQTTClient/MQTTClient/MQTTSessionManager.m | 174 +++--------------- .../MQTTClientTests/MQTTTestSessionManager.m | 24 ++- 4 files changed, 43 insertions(+), 291 deletions(-) diff --git a/MQTTClient/MQTTClient/ForegroundReconnection.m b/MQTTClient/MQTTClient/ForegroundReconnection.m index a84f257e..487d21ef 100644 --- a/MQTTClient/MQTTClient/ForegroundReconnection.m +++ b/MQTTClient/MQTTClient/ForegroundReconnection.m @@ -68,7 +68,7 @@ - (void)appDidEnterBackground { } - (void)appDidBecomeActive { - [self.sessionManager connectToLast]; + [self.sessionManager connectToLast:nil]; } - (void)endBackgroundTask { diff --git a/MQTTClient/MQTTClient/MQTTSessionManager.h b/MQTTClient/MQTTClient/MQTTSessionManager.h index 0c67cfdc..94e0a54a 100644 --- a/MQTTClient/MQTTClient/MQTTSessionManager.h +++ b/MQTTClient/MQTTClient/MQTTSessionManager.h @@ -167,36 +167,6 @@ typedef NS_ENUM(int, MQTTSessionManagerState) { connectInForeground:(BOOL)connectInForeground queue:(dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER; -/** initWithPersistence sets the MQTTPersistence properties other than default - * @param persistent YES or NO (default) to establish file or in memory persistence. - * @param maxWindowSize (a positive number, default is 16) to control the number of messages sent before waiting for acknowledgement in Qos 1 or 2. Additional messages are stored and transmitted later. - * @param maxSize (a positive number of bytes, default is 64 MB) to limit the size of the persistence file. Messages published after the limit is reached are dropped. - * @param maxMessages (a positive number, default is 1024) to limit the number of messages stored. Additional messages published are dropped. - * @param connectInForeground Whether or not to connect the MQTTSession when the app enters the foreground, and disconnect when it becomes inactive. When NO, the caller is responsible for calling -connectTo: and -disconnect. Defaults to YES. - * @param queue Queue for MQTTSession. - * @return the initialized MQTTSessionManager object - */ - -- (MQTTSessionManager *)initWithPersistence:(BOOL)persistent - maxWindowSize:(NSUInteger)maxWindowSize - maxMessages:(NSUInteger)maxMessages - maxSize:(NSUInteger)maxSize - connectInForeground:(BOOL)connectInForeground - queue:(dispatch_queue_t)queue; - -/** initWithPersistence sets the MQTTPersistence properties other than default - * @param persistent YES or NO (default) to establish file or in memory persistence. - * @param maxWindowSize (a positive number, default is 16) to control the number of messages sent before waiting for acknowledgement in Qos 1 or 2. Additional messages are stored and transmitted later. - * @param maxSize (a positive number of bytes, default is 64 MB) to limit the size of the persistence file. Messages published after the limit is reached are dropped. - * @param maxMessages (a positive number, default is 1024) to limit the number of messages stored. Additional messages published are dropped. - * @return the initialized MQTTSessionManager object - */ - -- (MQTTSessionManager *)initWithPersistence:(BOOL)persistent - maxWindowSize:(NSUInteger)maxWindowSize - maxMessages:(NSUInteger)maxMessages - maxSize:(NSUInteger)maxSize; - /** Connects to the MQTT broker and stores the parameters for subsequent reconnects * @param host specifies the hostname or ip address to connect to. Defaults to @"localhost". * @param port specifies the port to connect to @@ -215,6 +185,7 @@ typedef NS_ENUM(int, MQTTSessionManagerState) { * @param securityPolicy A custom SSL security policy or nil. * @param certificates An NSArray of the pinned certificates to use or nil. * @param protocolLevel Protocol version of the connection. + * @param connectHandler Called when first connected or if error occurred. It is not called on subsequent internal reconnects. */ - (void)connectTo:(NSString *)host @@ -233,109 +204,12 @@ typedef NS_ENUM(int, MQTTSessionManagerState) { withClientId:(NSString *)clientId securityPolicy:(MQTTSSLSecurityPolicy *)securityPolicy certificates:(NSArray *)certificates - protocolLevel:(MQTTProtocolVersion)protocolLevel; - -/** Connects to the MQTT broker and stores the parameters for subsequent reconnects - * @param host see connectTo description - * @param port see connectTo description - * @param tls see connectTo description - * @param keepalive see connectTo description - * @param clean see connectTo description - * @param auth see connectTo description - * @param user see connectTo description - * @param pass see connectTo description - * @param will see connectTo description - * @param willTopic see connectTo description - * @param willMsg see connectTo description - * @param willQos see connectTo description - * @param willRetainFlag see connectTo description - * @param clientId see connectTo description - * @param securityPolicy see connectTo description - * @param certificates An see connectTo description - */ - -- (void)connectTo:(NSString *)host - port:(NSInteger)port - tls:(BOOL)tls - keepalive:(NSInteger)keepalive - clean:(BOOL)clean - auth:(BOOL)auth - user:(NSString *)user - pass:(NSString *)pass - will:(BOOL)will - willTopic:(NSString *)willTopic - willMsg:(NSData *)willMsg - willQos:(MQTTQosLevel)willQos - willRetainFlag:(BOOL)willRetainFlag - withClientId:(NSString *)clientId - securityPolicy:(MQTTSSLSecurityPolicy *)securityPolicy - certificates:(NSArray *)certificates; - -/** Convenience alternative to full paramter connectTo - * @param host see connectTo description - * @param port see connectTo description - * @param tls see connectTo description - * @param keepalive see connectTo description - * @param clean see connectTo description - * @param auth see connectTo description - * @param user see connectTo description - * @param pass see connectTo description - * @param will see connectTo description - * @param willTopic see connectTo description - * @param willMsg see connectTo description - * @param willQos see connectTo description - * @param willRetainFlag see connectTo description - * @param clientId see connectTo description - */ - -- (void)connectTo:(NSString *)host - port:(NSInteger)port - tls:(BOOL)tls - keepalive:(NSInteger)keepalive - clean:(BOOL)clean - auth:(BOOL)auth - user:(NSString *)user - pass:(NSString *)pass - will:(BOOL)will - willTopic:(NSString *)willTopic - willMsg:(NSData *)willMsg - willQos:(MQTTQosLevel)willQos - willRetainFlag:(BOOL)willRetainFlag - withClientId:(NSString *)clientId; - -/** Convenience alternative to full paramter connectTo - * @param host see connectTo description - * @param port see connectTo description - * @param tls see connectTo description - * @param keepalive see connectTo description - * @param clean see connectTo description - * @param auth see connectTo description - * @param user see connectTo description - * @param pass see connectTo description - * @param willTopic the Will Topic is a string, must not be nil - * @param will the Will Message, might be zero length - * @param willQos see connectTo description - * @param willRetainFlag see connectTo description - * @param clientId see connectTo description - */ - -- (void)connectTo:(NSString *)host - port:(NSInteger)port - tls:(BOOL)tls - keepalive:(NSInteger)keepalive - clean:(BOOL)clean - auth:(BOOL)auth - user:(NSString *)user - pass:(NSString *)pass - willTopic:(NSString *)willTopic - will:(NSData *)will - willQos:(MQTTQosLevel)willQos - willRetainFlag:(BOOL)willRetainFlag - withClientId:(NSString *)clientId; + protocolLevel:(MQTTProtocolVersion)protocolLevel + connectHandler:(MQTTConnectHandler)connectHandler; /** Re-Connects to the MQTT broker using the parameters for given in the connectTo method */ -- (void)connectToLast; +- (void)connectToLast:(MQTTConnectHandler)connectHandler; /** publishes data on a given topic at a specified QoS level and retain flag diff --git a/MQTTClient/MQTTClient/MQTTSessionManager.m b/MQTTClient/MQTTClient/MQTTSessionManager.m index 1ce929e3..0880b39d 100644 --- a/MQTTClient/MQTTClient/MQTTSessionManager.m +++ b/MQTTClient/MQTTClient/MQTTSessionManager.m @@ -58,10 +58,20 @@ @interface MQTTSessionManager() #define RECONNECT_TIMER 1.0 #define RECONNECT_TIMER_MAX_DEFAULT 64.0 -#define BACKGROUND_DISCONNECT_AFTER 8.0 @implementation MQTTSessionManager +- (instancetype)init { + self = [self initWithPersistence:MQTT_PERSISTENT + maxWindowSize:MQTT_MAX_WINDOW_SIZE + maxMessages:MQTT_MAX_MESSAGES + maxSize:MQTT_MAX_SIZE + maxConnectionRetryInterval:RECONNECT_TIMER_MAX_DEFAULT + connectInForeground:YES + queue:dispatch_get_main_queue()]; + return self; +} + - (MQTTSessionManager *)initWithPersistence:(BOOL)persistent maxWindowSize:(NSUInteger)maxWindowSize maxMessages:(NSUInteger)maxMessages @@ -85,7 +95,7 @@ - (MQTTSessionManager *)initWithPersistence:(BOOL)persistent maxRetryInterval:maxRetryInterval queue:self.queue reconnectBlock:^{ - [weakSelf reconnect]; + [weakSelf reconnect:nil]; }]; #if TARGET_OS_IPHONE == 1 if (connectInForeground) { @@ -97,144 +107,6 @@ - (MQTTSessionManager *)initWithPersistence:(BOOL)persistent return self; } -- (MQTTSessionManager *)initWithPersistence:(BOOL)persistent - maxWindowSize:(NSUInteger)maxWindowSize - maxMessages:(NSUInteger)maxMessages - maxSize:(NSUInteger)maxSize - connectInForeground:(BOOL)connectInForeground - queue:(dispatch_queue_t)queue { - self = [self initWithPersistence:persistent - maxWindowSize:maxWindowSize - maxMessages:maxMessages - maxSize:maxSize - maxConnectionRetryInterval:RECONNECT_TIMER_MAX_DEFAULT - connectInForeground:connectInForeground - queue:queue]; - return self; -} - -- (instancetype)init { - self = [self initWithPersistence:MQTT_PERSISTENT - maxWindowSize:MQTT_MAX_WINDOW_SIZE - maxMessages:MQTT_MAX_MESSAGES - maxSize:MQTT_MAX_SIZE - maxConnectionRetryInterval:RECONNECT_TIMER_MAX_DEFAULT - connectInForeground:YES - queue:dispatch_get_main_queue()]; - return self; -} - -- (MQTTSessionManager *)initWithPersistence:(BOOL)persistent - maxWindowSize:(NSUInteger)maxWindowSize - maxMessages:(NSUInteger)maxMessages - maxSize:(NSUInteger)maxSize { - self = [self initWithPersistence:persistent - maxWindowSize:maxWindowSize - maxMessages:maxMessages - maxSize:maxSize - maxConnectionRetryInterval:RECONNECT_TIMER_MAX_DEFAULT - connectInForeground:YES - queue:dispatch_get_main_queue()]; - return self; -} - -- (void)connectTo:(NSString *)host - port:(NSInteger)port - tls:(BOOL)tls - keepalive:(NSInteger)keepalive - clean:(BOOL)clean - auth:(BOOL)auth - user:(NSString *)user - pass:(NSString *)pass - willTopic:(NSString *)willTopic - will:(NSData *)will - willQos:(MQTTQosLevel)willQos - willRetainFlag:(BOOL)willRetainFlag - withClientId:(NSString *)clientId { - [self connectTo:host - port:port - tls:tls - keepalive:keepalive - clean:clean - auth:auth - user:user - pass:pass - will:YES - willTopic:willTopic - willMsg:will - willQos:willQos - willRetainFlag:willRetainFlag - withClientId:clientId]; -} - -- (void)connectTo:(NSString *)host - port:(NSInteger)port - tls:(BOOL)tls - keepalive:(NSInteger)keepalive - clean:(BOOL)clean - auth:(BOOL)auth - user:(NSString *)user - pass:(NSString *)pass - will:(BOOL)will - willTopic:(NSString *)willTopic - willMsg:(NSData *)willMsg - willQos:(MQTTQosLevel)willQos - willRetainFlag:(BOOL)willRetainFlag - withClientId:(NSString *)clientId { - [self connectTo:host - port:port - tls:tls - keepalive:keepalive - clean:clean - auth:auth - user:user - pass:pass - will:will - willTopic:willTopic - willMsg:willMsg - willQos:willQos - willRetainFlag:willRetainFlag - withClientId:clientId - securityPolicy:nil - certificates:nil]; -} - -- (void)connectTo:(NSString *)host - port:(NSInteger)port - tls:(BOOL)tls - keepalive:(NSInteger)keepalive - clean:(BOOL)clean - auth:(BOOL)auth - user:(NSString *)user - pass:(NSString *)pass - will:(BOOL)will - willTopic:(NSString *)willTopic - willMsg:(NSData *)willMsg - willQos:(MQTTQosLevel)willQos - willRetainFlag:(BOOL)willRetainFlag - withClientId:(NSString *)clientId - securityPolicy:(MQTTSSLSecurityPolicy *)securityPolicy - certificates:(NSArray *)certificates { - [self connectTo:host - port:port - tls:tls - keepalive:keepalive - clean:clean - auth:auth - user:user - pass:pass - will:will - willTopic:willTopic - willMsg:willMsg - willQos:willQos - willRetainFlag:willRetainFlag - withClientId:clientId - securityPolicy:securityPolicy - certificates:certificates - protocolLevel:MQTTProtocolVersion311 // use this level as default, keeps it backwards compatible - ]; -} - - (void)connectTo:(NSString *)host port:(NSInteger)port tls:(BOOL)tls @@ -251,7 +123,8 @@ - (void)connectTo:(NSString *)host withClientId:(NSString *)clientId securityPolicy:(MQTTSSLSecurityPolicy *)securityPolicy certificates:(NSArray *)certificates - protocolLevel:(MQTTProtocolVersion)protocolLevel { + protocolLevel:(MQTTProtocolVersion)protocolLevel + connectHandler:(MQTTConnectHandler)connectHandler { DDLogVerbose(@"MQTTSessionManager connectTo:%@", host); BOOL shouldReconnect = self.session != nil; if (!self.session || @@ -318,16 +191,16 @@ - (void)connectTo:(NSString *)host if (shouldReconnect) { DDLogVerbose(@"[MQTTSessionManager] reconnecting"); [self disconnect]; - [self reconnect]; + [self reconnect:connectHandler]; } else { DDLogVerbose(@"[MQTTSessionManager] connecting"); - [self connectToInternal]; + [self connectToInternal:connectHandler]; } } - (UInt16)sendData:(NSData *)data topic:(NSString *)topic qos:(MQTTQosLevel)qos retain:(BOOL)retainFlag { if (self.state != MQTTSessionManagerStateConnected) { - [self connectToLast]; + [self connectToLast:nil]; } UInt16 msgId = [self.session publishData:data onTopic:topic @@ -453,26 +326,27 @@ - (void)messageDelivered:(MQTTSession *)session msgID:(UInt16)msgID { } -- (void)connectToInternal { +- (void)connectToInternal:(MQTTConnectHandler)connectHandler { if (self.session && self.state == MQTTSessionManagerStateStarting) { [self updateState:MQTTSessionManagerStateConnecting]; [self.session connectToHost:self.host port:self.port - usingSSL:self.tls]; + usingSSL:self.tls + connectHandler:connectHandler]; } } -- (void)reconnect { +- (void)reconnect:(MQTTConnectHandler)connectHandler { [self updateState:MQTTSessionManagerStateStarting]; - [self connectToInternal]; + [self connectToInternal:connectHandler]; } -- (void)connectToLast { +- (void)connectToLast:(MQTTConnectHandler)connectHandler { if (self.state == MQTTSessionManagerStateConnected) { return; } [self.reconnectTimer resetRetryInterval]; - [self reconnect]; + [self reconnect:connectHandler]; } - (void)triggerDelayedReconnect { diff --git a/MQTTClient/MQTTClientTests/MQTTTestSessionManager.m b/MQTTClient/MQTTClientTests/MQTTTestSessionManager.m index 6b087807..c0fc42c6 100644 --- a/MQTTClient/MQTTClientTests/MQTTTestSessionManager.m +++ b/MQTTClient/MQTTClientTests/MQTTTestSessionManager.m @@ -15,13 +15,13 @@ @interface MQTTSessionManager (Tests) -- (void)connectWithParameters:(NSDictionary *)parameters clean:(BOOL)clean; +- (void)connectWithParameters:(NSDictionary *)parameters clean:(BOOL)clean connectHandler:(MQTTConnectHandler)connectHandler; @end @implementation MQTTSessionManager (Tests) -- (void)connectWithParameters:(NSDictionary *)parameters clean:(BOOL)clean { +- (void)connectWithParameters:(NSDictionary *)parameters clean:(BOOL)clean connectHandler:(MQTTConnectHandler)connectHandler { [self connectTo:parameters[@"host"] port:[parameters[@"port"] intValue] tls:[parameters[@"tls"] boolValue] @@ -38,7 +38,8 @@ - (void)connectWithParameters:(NSDictionary *)parameters clean:(BOOL)clean { withClientId:nil securityPolicy:[MQTTTestHelpers securityPolicy:parameters] certificates:[MQTTTestHelpers clientCerts:parameters] - protocolLevel:[parameters[@"protocollevel"] intValue]]; + protocolLevel:[parameters[@"protocollevel"] intValue] + connectHandler:connectHandler]; } @end @@ -86,7 +87,7 @@ - (void)testMQTTSessionManager:(BOOL)clean { options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil]; manager.subscriptions = [@{TOPIC: @(0)} mutableCopy]; - [manager connectWithParameters:parameters clean:clean]; + [manager connectWithParameters:parameters clean:clean connectHandler:nil]; while (self.step == -1 && manager.state != MQTTSessionManagerStateConnected) { DDLogInfo(@"[testMQTTSessionManager] waiting for connect %d", manager.state); @@ -172,7 +173,10 @@ - (void)testMQTTSessionManagerPersistent { MQTTSessionManager *manager = [[MQTTSessionManager alloc] initWithPersistence:true maxWindowSize:2 maxMessages:1024 - maxSize:64*1024*1024]; + maxSize:64*1024*1024 + maxConnectionRetryInterval:64 + connectInForeground:NO + queue:dispatch_get_main_queue()]; manager.delegate = self; [manager addObserver:self forKeyPath:@"effectiveSubscriptions" @@ -180,7 +184,7 @@ - (void)testMQTTSessionManagerPersistent { context:nil]; manager.subscriptions = [@{TOPIC: @(0)} mutableCopy]; - [manager connectWithParameters:parameters clean:YES]; + [manager connectWithParameters:parameters clean:YES connectHandler:nil]; while (self.step == -1 && manager.state != MQTTSessionManagerStateConnected) { DDLogInfo(@"[testMQTTSessionManagerPersistent] waiting for connect %d", manager.state); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; @@ -267,7 +271,7 @@ - (void)testSessionManagerShort { manager.subscriptions = @{TOPIC: @(MQTTQosLevelExactlyOnce)}; - [manager connectWithParameters:parameters clean:YES]; + [manager connectWithParameters:parameters clean:YES connectHandler:nil]; while (!self.timedout && manager.state != MQTTSessionManagerStateConnected) { DDLogInfo(@"waiting for connect %d", manager.state); @@ -401,7 +405,7 @@ - (void)testSessionManagerALotSubscriptions { userInfo:nil repeats:false]; - [manager connectWithParameters:parameters clean:YES]; + [manager connectWithParameters:parameters clean:YES connectHandler:nil]; while (!self.timedout && manager.state != MQTTSessionManagerStateConnected) { DDLogInfo(@"waiting for connect %d", manager.state); @@ -636,7 +640,7 @@ - (void)testMQTTSessionManagerRecconnectionWithConnectToLast { MQTTSessionManager *manager = [[MQTTSessionManager alloc] init]; manager.delegate = self; - [manager connectWithParameters:parameters clean:YES]; + [manager connectWithParameters:parameters clean:YES connectHandler:nil]; while (self.step == -1 && manager.state != MQTTSessionManagerStateConnected) { DDLogInfo(@"[testMQTTSessionManager] waiting for connect %d", manager.state); @@ -653,7 +657,7 @@ - (void)testMQTTSessionManagerRecconnectionWithConnectToLast { [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; } - [manager connectToLast]; + [manager connectToLast:nil]; [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; XCTAssertEqual(manager.state, MQTTSessionManagerStateConnected);