// // AgentUtils.m // libindy-demo // // Created by Anastasia Tarasova on 22.06.17. // Copyright © 2017 Kirill Neznamov. All rights reserved. // #import "AgentUtils.h" #import #import "TestUtils.h" @interface AgentUtils () @property (atomic, strong) NSMutableDictionary* connectionCallbacks; @end @implementation AgentUtils + (AgentUtils *)sharedInstance { static AgentUtils *instance = nil; static dispatch_once_t dispatch_once_block; dispatch_once(&dispatch_once_block, ^ { instance = [AgentUtils new]; instance.connectionCallbacks = [NSMutableDictionary new]; }); return instance; } - (void)addMessageCallbackForConnection:(IndyHandle)connectionHandle { if (self.connectionCallbacks[@(connectionHandle)] == nil) { self.connectionCallbacks[@(connectionHandle)] = [NSArray new]; } } - (NSError *)connectWithPoolHandle:(IndyHandle)poolHandle walletHandle:(IndyHandle)walletHandle senderDid:(NSString *)senderDid receiverDid:(NSString *)receiverDid messageCallback:(void (^)(IndyHandle connectHandle, NSString *message))messageCallback outConnectionHandle:(IndyHandle *)outConnectionHandle { // connection callback. waiting for completion XCTestExpectation* connectCompletionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"listener completion finished"]; __block NSError *connectionErr; __block IndyHandle tempConnectionHandle; void (^onConnectCallback)(NSError*, IndyHandle) = ^(NSError *error, IndyHandle connectionHandle) { NSLog(@"AgentUtils::connectWithPoolHandle::OnConnectCallback triggered with code: %ld", (long)error.code); tempConnectionHandle = connectionHandle; connectionErr = error; [connectCompletionExpectation fulfill]; }; __weak typeof(self)weakSelf = self; weakSelf.connectionCallbacks[@(tempConnectionHandle)] = ^(IndyHandle xConnectionHandle, NSError *error, NSString *message) { NSLog(@"AgentUtils::connectWithPoolHandle::OnMessageCallback triggered invoced with error code: %ld", (long)error.code); if (messageCallback != nil) { messageCallback(xConnectionHandle, message);} }; NSError *ret = [IndyAgent connectWithPoolHandle:poolHandle walletHandle:walletHandle senderDId:senderDid receiverDId:receiverDid connectionHandler:onConnectCallback messageHandler:(void (^)(IndyHandle, NSError*, NSString*))weakSelf.connectionCallbacks[@(tempConnectionHandle)]]; if (ret.code != Success) { return ret; } // wait for connection callback [self waitForExpectations: @[connectCompletionExpectation] timeout:[TestUtils defaultTimeout]]; if (outConnectionHandle) { *outConnectionHandle = tempConnectionHandle;} return connectionErr; } __strong void (^onListenerCallback)(NSError*, IndyHandle) = nil; __strong void (^onMessageCallback)(IndyHandle, NSError*, NSString*) = nil; __strong void (^onConnectCallback)(IndyHandle, NSError*, IndyHandle, NSString*, NSString* ) = nil; - (NSError *)listenForEndpoint:(NSString *)endpoint connectionCallback:( void (^)(IndyHandle listenerHandle, IndyHandle connectionHandle))connectionCallback messageCallback:(void (^)(IndyHandle connectionHandle, NSString *message))messageCallback outListenerHandle:(IndyHandle *)listenerHandle { #if 0 // connection callback void (^onConnectCallback)(IndyHandle, NSError*, IndyHandle, NSString*, NSString* ) = ^(IndyHandle xListenerHandle, NSError *error, IndyHandle connectionHandle, NSString *senderDid, NSString *receiverDid) { NSLog(@"AgentUtils::listen::New connection %d on listener %d, err %ld, sender DID %@, receiver DID: %@", (int)connectionHandle, (int)xListenerHandle, (long)error.code, senderDid, receiverDid); if (connectionCallback) {connectionCallback(xListenerHandle, connectionHandle);} }; // listener callback. We need to obtain listenerHandle, so we wait for completion. Connection and message callnacks can be triggered multiple times later, so we just pass them to register. XCTestExpectation* listenerCompletionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"listener completion finished"]; __block IndyHandle tempListenerHandle = 0; __block NSError *listenerErr; void (^onListenerCallback)(NSError*, IndyHandle) = ^(NSError *error, IndyHandle xListenerHandle) { NSLog(@"OnListenerCallback triggered."); listenerErr = error; tempListenerHandle = xListenerHandle; [listenerCompletionExpectation fulfill]; }; // message callback void (^onMessageCallback)(IndyHandle, NSError*, NSString*) = ^(IndyHandle xConnectionHandle, NSError *error, NSString *message) { NSLog(@"AgentUtils::listen::On connection %d received (with error %ld) agent message (CLI->SRV): %@", (int)xConnectionHandle, (long)error.code, message); if (messageCallback != nil) { messageCallback(xConnectionHandle, message);} }; #endif // listener callback. We need to obtain listenerHandle, so we wait for completion. Connection and message callnacks can be triggered multiple times later, so we just pass them to register. XCTestExpectation* listenerCompletionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"listener completion finished"]; __block IndyHandle tempListenerHandle = 0; __block NSError *listenerErr; onConnectCallback = ^(IndyHandle xListenerHandle, NSError *error, IndyHandle connectionHandle, NSString *senderDid, NSString *receiverDid) { NSLog(@"AgentUtils::listen::New connection %d on listener %d, err %ld, sender DID %@, receiver DID: %@", (int)connectionHandle, (int)xListenerHandle, (long)error.code, senderDid, receiverDid); if (connectionCallback) {connectionCallback(xListenerHandle, connectionHandle);} }; onListenerCallback = ^(NSError *error, IndyHandle xListenerHandle) { NSLog(@"OnListenerCallback triggered."); listenerErr = error; tempListenerHandle = xListenerHandle; [listenerCompletionExpectation fulfill]; }; // message callback onMessageCallback = ^(IndyHandle xConnectionHandle, NSError *error, NSString *message) { NSLog(@"AgentUtils::listen::On connection %d received (with error %ld) agent message (CLI->SRV): %@", (int)xConnectionHandle, (long)error.code, message); if (messageCallback != nil) { messageCallback(xConnectionHandle, message);} }; // listen NSError *ret = [IndyAgent listenForEndpoint:endpoint listenerHandler:onListenerCallback connectionHandler:onConnectCallback messageHandler:onMessageCallback]; if (ret.code != Success) { NSLog(@"IndyAgent::listenWithWalletHandle failed with code: %ld", ret.code); return ret; } // wait for listenerCallback [self waitForExpectations: @[listenerCompletionExpectation] timeout:[TestUtils defaultTimeout]]; if (listenerHandle) { *listenerHandle = tempListenerHandle;}; return listenerErr; } - (NSError *)sendWithConnectionHandler:(IndyHandle)connectionHandle message:(NSString *)message { XCTestExpectation* completionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"completion finished"]; __block NSError *err; NSError *ret = [IndyAgent sendWithConnectionHandle:connectionHandle messsage:message completion:^(NSError *error) { err = error; [completionExpectation fulfill]; }]; if (ret.code != Success) { return ret; } [self waitForExpectations: @[completionExpectation] timeout:[TestUtils defaultTimeout]]; return err; } - (NSError *)closeConnection:(IndyHandle)connectionHandle { XCTestExpectation* completionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"completion finished"]; __block NSError *err; NSError *ret = [IndyAgent closeConnection:connectionHandle completion:^(NSError *error) { err = error; [completionExpectation fulfill]; }]; if (ret.code != Success) { return ret; } [self waitForExpectations: @[completionExpectation] timeout:[TestUtils defaultTimeout]]; return err; } - (NSError *)closeListener:(IndyHandle)listenerHandle { XCTestExpectation* completionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"completion finished"]; __block NSError *err; NSError *ret = [IndyAgent closeListener:listenerHandle completion:^(NSError *error) { err = error; [completionExpectation fulfill]; }]; if (ret.code != Success) { return ret; } [self waitForExpectations: @[completionExpectation] timeout:[TestUtils defaultTimeout]]; return err; } - (NSError *)addIdentityForListenerHandle:(IndyHandle)listenerHandle poolHandle:(IndyHandle)poolHandle walletHandle:(IndyHandle)walletHandle did:(NSString *)did { XCTestExpectation* completionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"completion finished"]; __block NSError *err; NSError *ret = [IndyAgent addIdentity:did forListenerHandle:listenerHandle poolHandle:poolHandle walletHandle:walletHandle completion:^(NSError *error) { err = error; [completionExpectation fulfill]; }]; if (ret.code != Success) { return ret; } [self waitForExpectations: @[completionExpectation] timeout:[TestUtils defaultTimeout]]; return err; } - (NSError *)removeIdentity:(NSString *) did listenerHandle:(IndyHandle)listenerHandle walletHandle:(IndyHandle)walletHandle { XCTestExpectation* completionExpectation = [[ XCTestExpectation alloc] initWithDescription: @"completion finished"]; __block NSError *err; NSError *ret = [IndyAgent removeIdentity:did forListenerHandle:listenerHandle walletHandle:walletHandle completion:^(NSError *error) { err = error; [completionExpectation fulfill]; }]; if (ret.code != Success) { return ret; } [self waitForExpectations: @[completionExpectation] timeout:[TestUtils defaultTimeout]]; return err; } @end