Files
eqn.ios/Sources/Earthquake Network/Models/EQNUser.m
T

223 lines
7.4 KiB
Objective-C

//
// EQNUser.m
// Earthquake Network
//
// Created by Luca Beretta on 20/09/18.
// Copyright © 2018 Luca Beretta. All rights reserved.
//
#import "EQNUser.h"
#import "Costanti.h"
#import "ServerRequest.h"
#import "EQNAccelerometroManager.h"
#import "EQNGeneratoreURLServer.h"
#import "EQNUtility.h"
#import "EQNManager.h"
@interface EQNUser ()
@property (strong, nonatomic) NSString *currentFirebaseToken;
@property (nonatomic) BOOL registrationInProgress;
@end
@implementation EQNUser
#pragma mark - Singleton
+ (instancetype)defaultUser
{
static EQNUser *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
#pragma mark - Init
- (instancetype)init
{
self = [super init];
if (self) {
self.registrationInProgress = NO;
self.user_ID = EQNUserData.sharedData.userId;
self.lastPosition = EQNUserData.sharedData.lastLocation;
[self registerForLocationUpdates];
}
return self;
}
#pragma mark - Public
- (void)saveUserInfo
{
[EQNUserData.sharedData saveFirebaseToken:self.currentFirebaseToken];
[EQNUserData.sharedData saveUserId:self.user_ID];
[EQNUserData.sharedData saveLastLocation:self.lastPosition];
}
- (void)removeUser
{
self.currentFirebaseToken = nil;
[EQNUserData.sharedData removeAllData];
}
#pragma mark - Public
- (void)retryUserRegistration
{
[self registerUserIfNeededWithFirebaseToken:self.currentFirebaseToken];
}
- (void)registerUserIfNeededWithFirebaseToken:(NSString *)firebaseToken
{
self.currentFirebaseToken = firebaseToken;
NSString *previousFirebaseToken = EQNUserData.sharedData.firebaseToken;
// dobbiamo effettuare la registrazione se:
// - userId non disponibile (si tratta di prima registrazione)
// - i due token di Firebase sono diversi (il token è stato aggiornato)
if (!self.user_ID) {
// prima registrazione dell'utente
NSLog(@"[EQNUser] perform first registration");
[self performServerRegistrationWithFirebaseToken:firebaseToken existingUserId:nil];
} else if (![previousFirebaseToken isEqualToString:firebaseToken]) {
// token cambiato, effettuiamo una nuova registrazione
NSLog(@"[EQNUser] firebase token is changed, update registration");
[self performServerRegistrationWithFirebaseToken:firebaseToken existingUserId:self.user_ID];
} else {
// non serve la registrazione, monitorniamo la posizione
NSLog(@"[EQNUser] user already registered, start location update");
[self registerForLocationUpdates];
}
}
- (void)downloadOfferTimeRemainingWithCompletion:(_Nonnull timeRemainingCompletion)completionHandler
{
NSURL *url = [EQNGeneratoreURLServer urlDownloadOfferTimeRemaining];
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:url richiesta:EQNTipoChiamataOfferTimeRemaining success:^(id result) {
NSInteger timeRemaining = 0;
if ([result isKindOfClass:[NSNumber class]]) {
NSNumber *timeRemainingNumber = (NSNumber *)result;
timeRemaining = [timeRemainingNumber integerValue];
} else if ([result isKindOfClass:[NSString class]]) {
NSString *timeRemainingString = (NSString *)result;
timeRemaining = [timeRemainingString integerValue];
}
completionHandler(timeRemaining);
} failure:^(NSError *error) {
completionHandler(0);
}];
}
#pragma mark - Network
- (void)performServerRegistrationWithFirebaseToken:(NSString *)token existingUserId:(NSString *)userId
{
if (self.registrationInProgress) {
NSLog(@"[EQNUser] Registration already in progress");
return;
}
if (token == nil) {
NSLog(@"[EQNUser] Firebase token is null, abort registration");
self.registrationInProgress = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:EQNServerRegistrationDidFailNotification object:nil];
return;
}
self.registrationInProgress = YES;
NSURL *url = [EQNGeneratoreURLServer urlRegistrazioneFirebaseToken:token existingUserId:userId];
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:url richiesta:EQNTipoChiamataRegistrazione success:^(id result) {
NSLog(@"[EQNUser] User registration completed");
// store userId
self.registrationInProgress = NO;
self.user_ID = [self convertUserIdIntoString:result];
[self saveUserInfo];
// inviamo, se già disponibile, la posizione al server
[self performServerSendLocation];
} failure:^(NSError *errore) {
NSLog(@"[EQNUser] Unable to perform user registration: %@", errore);
self.registrationInProgress = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:EQNServerRegistrationDidFailNotification object:nil];
}];
}
- (void)performServerSendLocation
{
if (!self.user_ID) {
NSLog(@"[EQNUser] User id not available");
return;
}
NSURL *url = [EQNGeneratoreURLServer urlPosizione];
[[ServerRequest defaultServerConnectionSingleton] inviaInformazioniAlServerWithURL:url richiesta:EQNTipoChiamataPosizione success:^(id result) {
if ([result isKindOfClass:[NSString class]]) {
NSString *stringResult = (NSString *)result;
if ([stringResult isEqualToString:@"reg"]) {
// l'utente non è stato trovato sul server, ri-eseguiamo la registrazione
NSLog(@"[EQNUser] User not found, retry registration");
[self retryUserRegistration];
} else {
NSLog(@"[EQNUser] Position saved on server");
}
}
[self saveUserInfo];
} failure:^(NSError *error) {
NSLog(@"[EQNUser] Unable to save position. Error: %@", error.localizedDescription);
}];
}
#pragma mark - Private
- (void)registerForLocationUpdates
{
[[EQNAccelerometroManager sharedInstance] addObserver:(id)self
forKeyPath:@"currentLocation"
options:NSKeyValueObservingOptionNew
context:nil];
[[EQNAccelerometroManager sharedInstance] startUpdatingLocationBackground];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"currentLocation"]) {
NSLog(@"[EQNUser] currentLocation changed");
// do some stuff
if (self.lastPosition) {
self.distanza = [self.lastPosition distanceFromLocation:[EQNAccelerometroManager sharedInstance].currentLocation];
}
self.lastPosition = [EQNAccelerometroManager sharedInstance].currentLocation;
[self performServerSendLocation];
if (![EQNManager defaultManager].isBackground) {
[[EQNAccelerometroManager sharedInstance] stopUpdatingLocation];
}
}
}
#pragma mark - Helpers
/// user_id saved as a Number, but is used as a NSString
- (NSString *)convertUserIdIntoString:(id)userId
{
if ([userId isKindOfClass:[NSString class]]) {
return (NSString *)userId;
} else if ([userId isKindOfClass:[NSNumber class]]) {
NSNumber *userIdNumber = (NSNumber *)userId;
return [userIdNumber stringValue];
} else {
return userId;
}
}
@end