You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/SignalUtilitiesKit/OWSDevicesService.m

127 lines
4.7 KiB
Objective-C

//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSDevicesService.h"
#import "NSNotificationCenter+OWS.h"
#import "OWSDevice.h"
#import "OWSError.h"
#import "OWSRequestFactory.h"
#import "TSNetworkManager.h"
#import <Mantle/MTLJSONAdapter.h>
#import <SessionProtocolKit/SessionProtocolKit.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const NSNotificationName_DeviceListUpdateSucceeded = @"NSNotificationName_DeviceListUpdateSucceeded";
NSString *const NSNotificationName_DeviceListUpdateFailed = @"NSNotificationName_DeviceListUpdateFailed";
NSString *const NSNotificationName_DeviceListUpdateModifiedDeviceList
= @"NSNotificationName_DeviceListUpdateModifiedDeviceList";
@implementation OWSDevicesService
+ (void)refreshDevices
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self
getDevicesWithSuccess:^(NSArray<OWSDevice *> *devices) {
// If we have more than one device; we may have a linked device.
if (devices.count > 1) {
// Setting this flag here shouldn't be necessary, but we do so
// because the "cost" is low and it will improve robustness.
[OWSDeviceManager.sharedManager setMayHaveLinkedDevices];
}
BOOL didAddOrRemove = [OWSDevice replaceAll:devices];
[NSNotificationCenter.defaultCenter
postNotificationNameAsync:NSNotificationName_DeviceListUpdateSucceeded
object:nil];
if (didAddOrRemove) {
[NSNotificationCenter.defaultCenter
postNotificationNameAsync:NSNotificationName_DeviceListUpdateModifiedDeviceList
object:nil];
}
}
failure:^(NSError *error) {
OWSLogError(@"Request device list failed with error: %@", error);
[NSNotificationCenter.defaultCenter postNotificationNameAsync:NSNotificationName_DeviceListUpdateFailed
object:error];
}];
});
}
+ (void)getDevicesWithSuccess:(void (^)(NSArray<OWSDevice *> *))successCallback
failure:(void (^)(NSError *))failureCallback
{
TSRequest *request = [OWSRequestFactory getDevicesRequest];
[[TSNetworkManager sharedManager] makeRequest:request
success:^(NSURLSessionDataTask *task, id responseObject) {
OWSLogVerbose(@"Get devices request succeeded");
NSArray<OWSDevice *> *devices = [self parseResponse:responseObject];
if (devices) {
successCallback(devices);
} else {
OWSLogError(@"unable to parse devices response:%@", responseObject);
NSError *error = OWSErrorMakeUnableToProcessServerResponseError();
failureCallback(error);
}
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
OWSLogVerbose(@"Get devices request failed with error: %@", error);
failureCallback(error);
}];
}
+ (void)unlinkDevice:(OWSDevice *)device
success:(void (^)(void))successCallback
failure:(void (^)(NSError *))failureCallback
{
TSRequest *request = [OWSRequestFactory deleteDeviceRequestWithDevice:device];
[[TSNetworkManager sharedManager] makeRequest:request
success:^(NSURLSessionDataTask *task, id responseObject) {
OWSLogVerbose(@"Delete device request succeeded");
successCallback();
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
OWSLogVerbose(@"Get devices request failed with error: %@", error);
failureCallback(error);
}];
}
+ (NSArray<OWSDevice *> *)parseResponse:(id)responseObject
{
if (![responseObject isKindOfClass:[NSDictionary class]]) {
OWSLogError(@"Device response was not a dictionary.");
return nil;
}
NSDictionary *response = (NSDictionary *)responseObject;
NSArray<NSDictionary *> *devicesAttributes = response[@"devices"];
if (!devicesAttributes) {
OWSLogError(@"Device response had no devices.");
return nil;
}
NSMutableArray<OWSDevice *> *devices = [NSMutableArray new];
for (NSDictionary *deviceAttributes in devicesAttributes) {
NSError *error;
OWSDevice *_Nullable device = [OWSDevice deviceFromJSONDictionary:deviceAttributes error:&error];
if (error || !device) {
OWSLogError(@"Failed to build device from dictionary with error: %@", error);
} else {
[devices addObject:device];
}
}
return [devices copy];
}
@end
NS_ASSUME_NONNULL_END