refactor: Better ServerRequest class

- Remove dead code
- Always call completion when handle the request
- Remove crazy checks when handle responses
This commit is contained in:
Andrea Busi
2020-09-25 13:04:10 +02:00
parent 1501b88a02
commit 4bb4815cd1
3 changed files with 139 additions and 435 deletions
+5
View File
@@ -9,6 +9,11 @@
#ifndef Costanti_h
#define Costanti_h
#pragma mark - Debug
/// Stampa le risposte delle chiamate al server
static BOOL const EQNDebugPrintResponse = NO;
#pragma mark - Urls
static NSString * const EQNWebsiteAddress = @"https://www.sismo.app";
+12 -11
View File
@@ -1,30 +1,31 @@
//
// ServerRequest.h
// Telegea
// Earthquake Network
//
// Created by Luca Beretta on 15/02/17.
// Copyright © 2017 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 25/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "Costanti.h"
NS_ASSUME_NONNULL_BEGIN
typedef void (^successCompletionHandler)(id _Nullable result);
typedef void (^errorCompletionHandler)(NSError * _Nullable error);
@interface ServerRequest : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate>
@property (nonatomic) BOOL isConnect;
+(ServerRequest *) defaultServerConnectionSingleton;
+ (instancetype)defaultServerConnectionSingleton;
-(void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata )chiamata success:(void(^)(id result)) success failure:(void(^)(NSError *))failure;
- (void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata)chiamata success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
-(void)inviaRicevuta:(NSData *)ricevuta success:(void(^)(id result)) success failure:(void(^)(NSError *))failure;
- (void)inviaRicevuta:(NSData *)ricevuta success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
/*
-(void)sendGetMethod:(NSURLRequest *)request typeRequest:(TypeRequest)type success:(void(^)(id dictionary)) success failure:(void(^)(NSError *))failure;
-(UIAlertController *)mostraAllertWithMessage:(NSString *)messaggio close:(void(^)(BOOL terminato))terminato;
*/
@end
NS_ASSUME_NONNULL_END
+122 -424
View File
@@ -1,9 +1,9 @@
//
// ServerRequest.m
// Telegea
// Earthquake Network
//
// Created by Luca Beretta on 15/02/17.
// Copyright © 2017 Luca Beretta. All rights reserved.
// Refactored by Andrea Busi on 25/09/2020.
// Copyright © 2020 Earthquake Network. All rights reserved.
//
#import "ServerRequest.h"
@@ -12,91 +12,76 @@
#import "EQNUtility.h"
#import "NSDictionary+BVJSONString.h"
//#import "User.h"
//#import "Portachiavi.h"
@interface ServerRequest (){
NSURLSession *session;
}
@property (nonatomic) Reachability *hostReachability;
@interface ServerRequest ()
@property (strong, nonatomic) NSURLSession *session;
@property (nonatomic) Reachability *internetReachability;
@end
@implementation ServerRequest
static ServerRequest *_sharedInstance = nil;
#pragma mark - Singleton
+(ServerRequest *) defaultServerConnectionSingleton{
@synchronized (_sharedInstance) {
+ (instancetype)defaultServerConnectionSingleton
{
static ServerRequest *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
#pragma mark - Init
- (instancetype)init
{
self = [super init];
if (self) {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config];
if (_sharedInstance == nil){
_sharedInstance = [[ServerRequest alloc] init];
}
[_sharedInstance initSingleton];
return _sharedInstance;
// registro notifiche rilevamento connessione
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
[self setValue:@([self updateConnectionReachability:self.internetReachability]) forKey:@"isConnect"];
}
return self;
}
#pragma mark - Reachability notifications
/// Called by Reachability whenever status changes.
- (void)reachabilityChanged:(NSNotification *)notification
{
if ([notification.object isKindOfClass:[Reachability class]]) {
Reachability *curReach = [notification object];
[self setValue:@([self updateConnectionReachability:curReach]) forKey:@"isConnect"];
}
}
-(void)initSingleton{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
session = [NSURLSession sessionWithConfiguration:config];
// registro notifiche rilevamento connessione
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
NSString *remoteHostName = @"http://srv.earthquakenetwork.it";
self.hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
[self.hostReachability startNotifier];
[self setValue:@([self updateConnectionhReachability:self.hostReachability]) forKey:@"isConnect"];
// self.isConnect = [self updateConnectionhReachability:self.hostReachability];
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
// self.isConnect = [self updateConnectionhReachability:self.internetReachability];
[self setValue:@([self updateConnectionhReachability:self.internetReachability]) forKey:@"isConnect"];
#pragma mark - Private
}
/*!
* Called by Reachability whenever status changes.
*/
- (void) reachabilityChanged:(NSNotification *)note
{
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
// self.isConnect = [self updateConnectionhReachability:curReach];
[self setValue:@([self updateConnectionhReachability:curReach]) forKey:@"isConnect"];
}
- (BOOL)updateConnectionhReachability:(Reachability *)reachability
- (BOOL)updateConnectionReachability:(Reachability *)reachability
{
NetworkStatus netStatus = [reachability currentReachabilityStatus];
switch (netStatus) {
case NotReachable:
return NO;
break;
default:
return YES;
break;
case NotReachable: return NO;
default: return YES;
}
}
-(void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata )chiamata success:(void(^)(id result)) success failure:(void(^)(NSError *))failure{
#pragma mark - Public
- (void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata)chiamata success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure
{
if (!self.isConnect) {
NSLog(@"[ServerRequest] not connected, return error");
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:401 userInfo:@{MESSAGGIO : NSLocalizedString(@"Nessuna connessione", @"messaggio assenza connesione")}];
failure(error);
onFailure(error);
// todo Andrea: perchè non viene fatto return? era già così
}
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
@@ -106,166 +91,76 @@ static ServerRequest *_sharedInstance = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
});
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if (error) {
NSLog(@"[ServerRequest] response error: %@", error.localizedDescription);
onFailure(error);
return;
}
if(!error){
NSError *jsonError;
// NSData *myRequestData = [response dataUsingEncoding:NSUTF8StringEncoding];
id JSON = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonError];
if (!jsonError){
switch (httpResp.statusCode) {
case 200:
switch (chiamata) {
case registrazione:
success(JSON);
break;
case posizione:
success(@"success");
break;
case calibrazione:
success(JSON);
break;
case rilevamento:
success(JSON);
break;
case downloadDati:
success(JSON);
break;
case graficoSmartPhone:
success(JSON);
break;
case areaCheck:
success(JSON);
break;
case pastquakes:
success(JSON);
break;
case utentiDisponibili:
success(JSON);
break;
case segnalazioneManuale:
success(JSON);
break;
case tsunami:
success(JSON);
break;
case segnalazzioneTerremoto:
success(JSON);
break;
case commentoTerremoto:
success(JSON);
break;
case tempoDisponibile:
success(JSON);
break;
case impostazioniNotifiche:
success(JSON);
break;
case offerTimeRemaining:
success(JSON);
default:
break;
}
// NSLog(@"Risultato richiesta server %@", JSON);
// success(@"");
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}
NSError *jsonError;
id JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
if (!jsonError){
if (EQNDebugPrintResponse) {
NSLog(@"[ServerRequest] response json: %@", JSON);
}
else{
NSString* newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (newStr) {
if (chiamata == segnalazzioneTerremoto) {
NSLog(@"risultato segnalazione %@", [EQNUtility clearStringMessaggi:newStr]);
success([EQNUtility clearStringMessaggi:newStr]);
switch (httpResp.statusCode) {
case 200:
switch (chiamata) {
case posizione:
onSuccess(@"success");
break;
default:
onSuccess(JSON);
break;
}
if (chiamata == rilevamento) {
/// NSLog(@"newStr %@", newStr);
success([EQNUtility clearStringMessaggi:newStr]);
}
if (chiamata == registrazione) {
NSLog(@"newStr %@", newStr);
}
if (chiamata == tempoDisponibile) {
NSLog(@"newStr %@", newStr);
}
if (chiamata == calibrazione) {
NSLog(@"calibrazione %@", newStr);
success(newStr);
}
if (chiamata == rilevamento) {
success(newStr);
}
if (chiamata == impostazioniNotifiche) {
NSLog(@"impostazioniNotifiche %@", newStr);
success(newStr);
}
if (chiamata == segnalazioneManuale) {
NSLog(@"segnalazioneManuale %@", newStr);
}
} else{
NSLog(@"Error %@", [jsonError description]);
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Username e Password sbagliati", @"messaggio errore inserimento credenziali")}];
failure(error);
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}
}
} else {
NSString *newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (newStr) {
if (EQNDebugPrintResponse) {
NSLog(@"[ServerRequest] response string: %@", newStr);
}
switch (chiamata) {
case segnalazzioneTerremoto:
onSuccess([EQNUtility clearStringMessaggi:newStr]);
break;
case rilevamento:
onSuccess([EQNUtility clearStringMessaggi:newStr]);
break;
case calibrazione:
onSuccess(newStr);
break;
case impostazioniNotifiche:
onSuccess(newStr);
default:
// don't call the callback
break;
}
} else {
NSLog(@"[ServerRequest] Unable to create string with response: %@", [jsonError description]);
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Username e Password sbagliati", @"messaggio errore inserimento credenziali")}];
onFailure(error);
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}
}
}];
[dataTask resume];
}
-(void)inviaRicevuta:(NSData *)ricevuta success:(void(^)(id result)) success failure:(void(^)(NSError *))failure{
- (void)inviaRicevuta:(NSData *)ricevuta success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure
{
NSString *jsonObjectString = [ricevuta base64EncodedStringWithOptions:0];
// NSString* BASEURl = @"XXXXXXXXX/XXX/XXXX";
// NSString *testReceipt= [BASEURl stringByAppendingString:@"/InApp/iOS/updatePurchase"];
NSDictionary *params = @{@"ricevuta" :jsonObjectString};
NSString *parametri = [params bv_jsonStringWithPrettyPrint:YES];
@@ -275,226 +170,29 @@ static ServerRequest *_sharedInstance = nil;
[urlRequest addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[urlRequest setHTTPBody:[parametri dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if(!error){
NSError *jsonError;
// NSData *myRequestData = [response dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonError];
if (!jsonError){
switch (httpResp.statusCode) {
case 200:
success(JSON);
break;
default:
NSLog(@"httpResp.statusCode %ld", (long)httpResp.statusCode);
break;
}
}
}
else{
failure(error.userInfo[@"NSLocalizedDescription"]);
NSLog(@"Error %@", error.userInfo);
if (error) {
NSLog(@"[ServerRequest] inviaRicevuta | response error: %@", error.localizedDescription);
onFailure(error.userInfo[@"NSLocalizedDescription"]);
return;
}
}];
[dataTask resume];
}
/*
-(void)sendGetMethod:(NSURLRequest *)request typeRequest:(TypeRequest)type success:(void(^)(id dictionary)) success failure:(void(^)(NSError *))failure{
if (!self.isConnect) {
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:401 userInfo:@{MESSAGGIO : NSLocalizedString(@"Nessuna connessione", @"messaggio assenza connesione")}];
failure(error);
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if(!error){
NSError *jsonError;
NSDictionary *showJSON = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonError];
if (!jsonError){
switch (httpResp.statusCode) {
case 200:
success(showJSON);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
break;
}
NSError *jsonError;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
if (!jsonError) {
switch (httpResp.statusCode) {
case 200:
onSuccess(JSON);
break;
default:
NSLog(@"[ServerRequest] inviaRicevuta | response error, status code: %ld", (long)httpResp.statusCode);
break;
}
else{
NSError *error;
switch (type) {
case login:
error = [NSError errorWithDomain:NSMachErrorDomain code:login userInfo:@{MESSAGGIO : NSLocalizedString(@"Username e Password sbagliati", @"messaggio errore inserimento credenziali")}];
break;
case reading:
error = [NSError errorWithDomain:NSMachErrorDomain code:reading userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore! Impossibile accedere all'impianto", @"messaggio errore richiesta apikey impianto")}];
break;
case sending:
// error = [NSError errorWithDomain:NSMachErrorDomain code:httpResp.statusCode userInfo:@{MESSAGGIO : NSLocalizedString(@"sending", @"")}];
case zona:
error = [NSError errorWithDomain:NSMachErrorDomain code:zona userInfo:@{MESSAGGIO : NSLocalizedString(@"Sì è verificato un errore sulla centralina", @"messaggio errore richiesta dev_cmd")}];
break;
default:
error = [NSError errorWithDomain:NSMachErrorDomain code:httpResp.statusCode userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore sconosciuto", @"")}];
break;
}
failure(error);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
}
}];
[dataTask resume];
}
-(void)caricaImpianto:(Plant *)plant success:(void(^)(BOOL))success failure:(void(^)(NSError *))failure{
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[self urlWithInfo:plant]];
[urlRequest setHTTPMethod:@"GET"];
[self sendGetMethod:urlRequest
typeRequest:login
success:^(NSDictionary *result){
plant.apikey = result[@"apikey"];
[self caricaZoneiWithPlant:plant success:^(BOOL result){
// caricamento zone
success(result);
}failure:^(NSError *error){
// caricamento zone
failure(error);
}];
}
failure:^(NSError *error){
// caricamento impianto
failure(error);
}];
}
-(NSURL *)urlWithInfo:(Plant *)plant{
NSURL *url =[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@=%@&%@=%@&%@=%@", LOGIN_URL, USERNAME, [User defaultUser].nome, PSW, [Portachiavi getCredenziali:[User defaultUser].nome], PLANT_ID, plant.plant_id]];
return url;
}
-(void)caricaZoneiWithPlant:(Plant *)plant success:(void(^)(BOOL))success failure:(void(^)(NSError *))failure{
NSString *url = [NSString stringWithFormat:@"%@?%@=%@&%@=%@&%@=[{\"mod\":10,\"reg\":100}]", DEVICE_COMMANDS_URL, APIKEY, plant.apikey, PLANT_ID, plant.plant_id, DEV_CMD];
NSURL *theUrl = [NSURL URLWithString:[url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:theUrl];
[urlRequest setHTTPMethod:@"GET"];
[self sendGetMethod:urlRequest
typeRequest:reading
success:^(NSDictionary *result){
NSArray *valori = result[@"result"];
NSNumber *numeroZone;
if(valori.count == 0){
//numeroZone = @1;
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore! Impossibile accedere all'impianto", @"messaggio errore richiesta apikey impianto")}];
failure(error);
return ;
}
else if([[valori firstObject][@"val"] isEqual:[NSNull null]]){
//numeroZone = @1;
NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:0 userInfo:@{MESSAGGIO : NSLocalizedString(@"Errore! Impossibile accedere all'impianto", @"messaggio errore richiesta apikey impianto")}];
failure(error);
return ;
}
else
numeroZone = [valori firstObject][@"val"];
[plant creaZone:[numeroZone intValue]];
success(YES);
}
failure:^(NSError *error){
failure(error);
}];
}
-(UIAlertController *)mostraAllertWithMessage:(NSString *)messaggio close:(void(^)(BOOL terminato))terminato{
NSString *titolo = @"";
if ([messaggio isEqualToString:NSLocalizedString(@"Nessuna connessione", @"messaggio assenza connesione")])
titolo = NSLocalizedString(@"Attenzione", @"");
UIAlertController* alert = [UIAlertController alertControllerWithTitle:titolo//NSLocalizedString(@"Attenzione", @"")
message:messaggio
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
terminato(YES);
}];
[alert addAction:defaultAction];
return alert;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
}
*/
@end