diff --git a/Classes/Utils/XMLRPCHelper.h b/Classes/Utils/XMLRPCHelper.h new file mode 100644 index 000000000..85edf3ddc --- /dev/null +++ b/Classes/Utils/XMLRPCHelper.h @@ -0,0 +1,39 @@ +// +// UrmetXMLRPC.h +// IperVoice +// +// Created by guillaume on 27/05/2015. +// Copyright (c) 2015 Urmet. All rights reserved. +// + +#import +#import +#import +#import +#import + +@interface XMLRPCHelper : NSObject +/* This class is only here to handle XMLRPC responses. + * + * The implementation for didReceiveResponse: (XMLRPCResponse *)response will check if the XMLRPC + * responded 'OK', in which case the view will return to idle, or if there is an error, an + * Alert will be displayed with the error message. + * + * All the rest is implemented to do nothing, which is what we want for Urmet + */ + +/** + * Will send the XML request to the 'xmlrpc_url' server that is defined in the 'assistant' section + * of the linphonerc file. + * You must implement the - didReceiveResponse method if you are using this. + */ +- (void)sendXMLRequestMethod:(NSString *)method withParams:(NSArray *)params; +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *response))block; +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *response))successBlock + onError:(BOOL (^)(XMLRPCRequest *request))errorBlock; + +@end diff --git a/Classes/Utils/XMLRPCHelper.m b/Classes/Utils/XMLRPCHelper.m new file mode 100644 index 000000000..8b544c086 --- /dev/null +++ b/Classes/Utils/XMLRPCHelper.m @@ -0,0 +1,121 @@ +// +// UrmetXMLRPC.m +// IperVoice +// +// Created by guillaume on 01/06/2015. +// Copyright (c) 2015 Urmet. All rights reserved. +// + +#import + +#import "LinphoneManager.h" +#import "DTAlertView.h" +#import "XMLRPCHelper.h" +#import "Utils.h" + +/* This subclass allows use to store the block to execute on success */ +@interface UrmetXMLRPCRequest : XMLRPCRequest +@property(copy, nonatomic) BOOL (^successBlock)(XMLRPCResponse *response); +@property(copy, nonatomic) BOOL (^xmlErrorBlock)(XMLRPCRequest *request); +@end + +@implementation XMLRPCHelper + +#pragma mark - API + +- (void)sendXMLRequestMethod:(NSString *)method withParams:(NSArray *)params { + [self sendXMLRequestMethod:method withParams:params onSuccess:nil onError:nil]; +} + +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *))successBlock { + [self sendXMLRequestMethod:method withParams:params onSuccess:successBlock onError:nil]; +} + +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *))successBlock + onError:(BOOL (^)(XMLRPCRequest *req))errorBlock { + LOGI(@"XMLRPC %@ - %@", method, params); + NSURL *URL = + [NSURL URLWithString:[LinphoneManager.instance lpConfigStringForKey:@"xmlrpc_url" forSection:@"assistant"]]; + UrmetXMLRPCRequest *request = [[UrmetXMLRPCRequest alloc] initWithURL:URL]; + [request setMethod:method withParameters:params]; + if (successBlock) { + request.successBlock = successBlock; + } + if (errorBlock) { + request.xmlErrorBlock = errorBlock; + } + + XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; + [manager spawnConnectionWithXMLRPCRequest:request delegate:self]; +} + +#pragma mark - XMLRPCConnectionHandler delegate + +- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { + + UrmetXMLRPCRequest *req = (UrmetXMLRPCRequest *)request; + NSString *error = nil; + BOOL handleHere = YES; + + LOGI(@"XMLRPC %@ - %@", [request method], [response body]); + + if (req.successBlock) { + handleHere = req.successBlock(response); + } + if (!handleHere) + return; + + if ([response isFault]) { + error = response.faultString; + } else if (response.object != nil && ![response.object isEqualToString:@"OK"]) { + error = NSLocalizedString(@"Unknown error", nil); + } else if ([response.object isEqualToString:@"OK"]) { + // do nothing, if the client is interested in the response he will have handled it + } else { + LOGE(@"Empty object for XMLRPC response: HTTP error"); + error = NSLocalizedString(@"(no description)", nil); + } + + if (error != nil) { + [self displayErrorPopup:error]; + } +} + +- (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error { + UrmetXMLRPCRequest *req = (UrmetXMLRPCRequest *)request; + BOOL handleHere = YES; + if (req.xmlErrorBlock) { + handleHere = req.xmlErrorBlock(request); + } + if (!handleHere) + return; + // do not display technical message to the user.. + [self displayErrorPopup:NSLocalizedString(@"Server error", nil)]; // error.localizedDescription]; + LOGE(@"requestDidFailWithError: %@", error.localizedDescription); +} + +- (BOOL)request:(XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { + return NO; +} + +- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + /* Do nothing, not needed */ +} + +- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + /* Do nothing, not needed */ +} + +#pragma mark - Error alerts + +- (void)displayErrorPopup:(NSString *)error { + DTAlertView *av = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Server request error", nil) message:error]; + [av addCancelButtonWithTitle:NSLocalizedString(@"OK", nil) block:nil]; + [av show]; +} + +@end diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index d5d89cb9e..746301884 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ 63058AE31B4E93B300EFAE36 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = 63058AE11B4E93A100EFAE36 /* tester_hosts */; }; 6306440E1BECB08500134C72 /* FirstLoginView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6306440C1BECB08500134C72 /* FirstLoginView.m */; }; 6306440F1BECB08500134C72 /* FirstLoginView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6306440D1BECB08500134C72 /* FirstLoginView.xib */; }; + 6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */; }; 630CF5571AF7CE1500539F7A /* UITextField+DoneButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 630CF5561AF7CE1500539F7A /* UITextField+DoneButton.m */; }; 631348301B6F7B6600C6BDCB /* UIRoundBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 6313482F1B6F7B6600C6BDCB /* UIRoundBorderedButton.m */; }; 631348321B6FA53300C6BDCB /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 631348311B6FA53300C6BDCB /* rootca.pem */; }; @@ -890,6 +891,8 @@ 6306440B1BECB08500134C72 /* FirstLoginView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FirstLoginView.h; sourceTree = ""; }; 6306440C1BECB08500134C72 /* FirstLoginView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FirstLoginView.m; sourceTree = ""; }; 6306440D1BECB08500134C72 /* FirstLoginView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FirstLoginView.xib; sourceTree = ""; }; + 6308F9C31BF0DD6600D1234B /* XMLRPCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLRPCHelper.h; path = Utils/XMLRPCHelper.h; sourceTree = ""; }; + 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMLRPCHelper.m; path = Utils/XMLRPCHelper.m; sourceTree = ""; }; 630CF5551AF7CE1500539F7A /* UITextField+DoneButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+DoneButton.h"; sourceTree = ""; }; 630CF5561AF7CE1500539F7A /* UITextField+DoneButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+DoneButton.m"; sourceTree = ""; }; 6313482E1B6F7B6600C6BDCB /* UIRoundBorderedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundBorderedButton.h; sourceTree = ""; }; @@ -2540,12 +2543,14 @@ D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */, 6371579F1B283FE200C91677 /* FileTransferDelegate.h */, 637157A01B283FE200C91677 /* FileTransferDelegate.m */, - 63B81A021B57DA33009604A6 /* TPKeyboardAvoiding */, D3ED40141602172200BF332B /* GrowingTextView */, D3807FC715C2894A005BE9BC /* InAppSettingsKit */, D326483615887D5200930C67 /* OrderedDictionary.h */, D326483715887D5200930C67 /* OrderedDictionary.m */, + 63B81A021B57DA33009604A6 /* TPKeyboardAvoiding */, D3F7997E15BD31EC0018C273 /* TPMultiLayoutViewController */, + 6308F9C31BF0DD6600D1234B /* XMLRPCHelper.h */, + 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */, C9B3A6FD15B485DB006F52EE /* Utils.h */, D35860D515B549B500513429 /* Utils.m */, D3554EC515CA79A900478841 /* XMLRPC.xcodeproj */, @@ -3411,6 +3416,7 @@ 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */, D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */, 6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */, + 6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */, D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */, D3ED3EA71587334E006C0DE4 /* HistoryListTableView.m in Sources */, D3ED3EB81587392C006C0DE4 /* HistoryListView.m in Sources */,