FBSimulatorControl/Notifiers/FBCoreSimulatorNotifier.m (74 lines of code) (raw):
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "FBCoreSimulatorNotifier.h"
#import <CoreSimulator/SimDevice.h>
#import <CoreSimulator/SimDeviceNotificationManager.h>
#import <CoreSimulator/SimDeviceNotifier-Protocol.h>
#import <CoreSimulator/SimDeviceSet.h>
#import "FBSimulator.h"
#import "FBSimulatorSet.h"
@interface FBCoreSimulatorNotifier ()
@property (nonatomic, readonly, assign) NSUInteger handle;
@property (nonatomic, readonly, strong) id notifier;
@end
@implementation FBCoreSimulatorNotifier
#pragma mark Public
+ (instancetype)notifierForSimDevice:(SimDevice *)simDevice queue:(dispatch_queue_t)queue block:(void (^)(NSDictionary<NSString *, id> *info))block
{
id<NSObject, SimDeviceNotifier> notifier = simDevice.notificationManager;
return [[self alloc] initWithNotifier:notifier queue:queue block:block];
}
+ (FBFuture<NSNull *> *)resolveLeavesState:(FBiOSTargetState)state forSimDevice:(SimDevice *)device
{
FBMutableFuture<NSNull *> *future = FBMutableFuture.future;
dispatch_queue_t queue = dispatch_queue_create("com.facebook.fbsimulatorcontrol.resolve_state", DISPATCH_QUEUE_SERIAL);
FBCoreSimulatorNotifier *notifier = [self notifierForSimDevice:device queue:queue block:^(NSDictionary<NSString *, id> *info) {
if (![info[@"notification"] isEqualToString:@"device_state"]) {
return;
}
NSNumber *newStateNumber = info[@"new_state"];
if (!newStateNumber) {
return;
}
FBiOSTargetState newState = newStateNumber.unsignedIntegerValue;
if (newState == state) {
return;
}
[future resolveWithResult:NSNull.null];
}];
return [future
onQueue:queue notifyOfCompletion:^(id _) {
[notifier terminate];
}];
}
- (void)terminate
{
[self.notifier unregisterNotificationHandler:self.handle error:nil];
}
#pragma mark Private
+ (instancetype)notifierForSet:(FBSimulatorSet *)set queue:(dispatch_queue_t)queue block:(void (^)(NSDictionary<NSString *, id> *info))block
{
id<NSObject, SimDeviceNotifier> notifier = set.deviceSet.notificationManager;
return [[self alloc] initWithNotifier:notifier queue:queue block:block];
}
- (instancetype)initWithNotifier:(id<NSObject, SimDeviceNotifier>)notifier queue:(dispatch_queue_t)queue block:(void (^)(NSDictionary<NSString *, id> *info))block
{
self = [super init];
if (!self) {
return nil;
}
_notifier = notifier;
_handle = [FBCoreSimulatorNotifier registerNotificationHandler:notifier queue:queue handler:block];
return self;
}
+ (NSUInteger)registerNotificationHandler:(id<NSObject, SimDeviceNotifier>)notifier queue:(dispatch_queue_t)queue handler:(void (^)(NSDictionary<NSString *, id> *))handler
{
if ([notifier respondsToSelector:@selector(registerNotificationHandlerOnQueue:handler:)]) {
return [notifier registerNotificationHandlerOnQueue:queue handler:handler];
} else {
return [notifier registerNotificationHandler:^(NSDictionary *info) {
dispatch_async(queue, ^{
handler(info);
});
}];
}
}
@end