VLCNotificationRelay.m 3.7 KB

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