VLCNotificationRelay.m 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //
  2. // VLCNotificationRelay.m
  3. // VLC for iOS
  4. //
  5. // Created by Tobias Conradi on 02.04.15.
  6. // Copyright (c) 2015 VideoLAN. All rights reserved.
  7. //
  8. #import "VLCNotificationRelay.h"
  9. @interface VLCNotificationRelay ()
  10. @property (nonatomic, readonly) NSMutableDictionary *localToRemote;
  11. @property (nonatomic, readonly) NSMutableDictionary *remoteToLocal;
  12. @end
  13. @implementation VLCNotificationRelay
  14. + (instancetype)sharedRelay
  15. {
  16. static dispatch_once_t onceToken;
  17. static VLCNotificationRelay *instance;
  18. dispatch_once(&onceToken, ^{
  19. instance = [VLCNotificationRelay new];
  20. });
  21. return instance;
  22. }
  23. - (instancetype)init
  24. {
  25. self = [super init];
  26. if (self) {
  27. _localToRemote = [NSMutableDictionary dictionary];
  28. _remoteToLocal = [NSMutableDictionary dictionary];
  29. }
  30. return self;
  31. }
  32. - (void)dealloc {
  33. [[NSNotificationCenter defaultCenter] removeObserver:self];
  34. CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
  35. CFNotificationCenterRemoveObserver(center, (__bridge const void *)(self), NULL, NULL);
  36. }
  37. - (void)addRelayLocalName:(NSString *)localName toRemoteName:(NSString *)remoteName {
  38. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localNotification:) name:localName object:nil];
  39. self.localToRemote[localName] = remoteName;
  40. }
  41. - (void)removeRelayLocalName:(NSString *)localName {
  42. [[NSNotificationCenter defaultCenter] removeObserver:self name:localName object:nil];
  43. [self.localToRemote removeObjectForKey:localName];
  44. }
  45. - (void)addRelayRemoteName:(NSString *)remoteName toLocalName:(NSString *)localName {
  46. CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
  47. CFNotificationCenterAddObserver(center, (__bridge const void *)(self), notificationCallback, (__bridge CFStringRef)remoteName, NULL, CFNotificationSuspensionBehaviorHold);
  48. self.remoteToLocal[remoteName] = localName;
  49. }
  50. - (void)removeRelayRemoteName:(NSString *)remoteName {
  51. CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
  52. CFNotificationCenterRemoveObserver(center, (__bridge const void *)(self), (__bridge CFStringRef)remoteName, NULL);
  53. [self.remoteToLocal removeObjectForKey:remoteName];
  54. }
  55. #pragma mark - notification handeling
  56. - (void)localNotification:(NSNotification *)notification {
  57. NSString *localName = notification.name;
  58. NSString *remoteName = self.localToRemote[localName];
  59. /*
  60. * in current version of iOS this is ignored for the darwin center
  61. * nevertheless we use it to be future proof
  62. */
  63. NSDictionary *userInfo = notification.userInfo;
  64. CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
  65. CFNotificationCenterPostNotification(center, (__bridge CFStringRef)remoteName, NULL, (__bridge CFDictionaryRef)userInfo, false);
  66. }
  67. static void notificationCallback(CFNotificationCenterRef center, void* observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
  68. {
  69. VLCNotificationRelay *relay = (__bridge VLCNotificationRelay*) observer;
  70. NSString *remoteName = (__bridge NSString *)name;
  71. NSString *localName = relay.remoteToLocal[remoteName];
  72. /*
  73. * in current version of iOS this is ignored for the darwin center
  74. * nevertheless we use it to be future proof
  75. */
  76. NSDictionary *dict = (__bridge NSDictionary *)userInfo;
  77. [[NSNotificationCenter defaultCenter] postNotificationName:localName object:nil userInfo:dict];
  78. }
  79. @end