QNNetworkStatusManager.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // QNNetworkStatusManager.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2020/11/17.
  6. // Copyright © 2020 Qiniu. All rights reserved.
  7. //
  8. #import "QNUtils.h"
  9. #import "QNAsyncRun.h"
  10. #import "QNFileRecorder.h"
  11. #import "QNRecorderDelegate.h"
  12. #import "QNNetworkStatusManager.h"
  13. @interface QNNetworkStatus()
  14. @property(nonatomic, assign)int speed;
  15. @end
  16. @implementation QNNetworkStatus
  17. - (instancetype)init{
  18. if (self = [super init]) {
  19. _speed = 200;
  20. }
  21. return self;
  22. }
  23. - (NSDictionary *)toDictionary{
  24. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  25. [dictionary setObject:@(self.speed) forKey:@"speed"];
  26. return dictionary;
  27. }
  28. + (QNNetworkStatus *)statusFromDictionary:(NSDictionary *)dictionary{
  29. QNNetworkStatus *status = [[QNNetworkStatus alloc] init];
  30. status.speed = [dictionary[@"speed"] intValue];
  31. return status;
  32. }
  33. @end
  34. @interface QNNetworkStatusManager()
  35. @property(nonatomic, assign)BOOL isHandlingNetworkInfoOfDisk;
  36. @property(nonatomic, strong)id<QNRecorderDelegate> recorder;
  37. @property(nonatomic, strong)NSMutableDictionary<NSString *, QNNetworkStatus *> *networkStatusInfo;
  38. @end
  39. @implementation QNNetworkStatusManager
  40. + (instancetype)sharedInstance{
  41. static QNNetworkStatusManager *manager = nil;
  42. static dispatch_once_t onceToken;
  43. dispatch_once(&onceToken, ^{
  44. manager = [[QNNetworkStatusManager alloc] init];
  45. [manager initData];
  46. });
  47. return manager;
  48. }
  49. - (void)initData{
  50. self.isHandlingNetworkInfoOfDisk = NO;
  51. self.networkStatusInfo = [NSMutableDictionary dictionary];
  52. self.recorder = [QNFileRecorder fileRecorderWithFolder:[[QNUtils sdkCacheDirectory] stringByAppendingString:@"/NetworkStatus"] error:nil];
  53. [self asyncRecoverNetworkStatusFromDisk];
  54. }
  55. + (NSString *)getNetworkStatusType:(NSString *)host
  56. ip:(NSString *)ip {
  57. return [QNUtils getIpType:ip host:host];
  58. }
  59. - (QNNetworkStatus *)getNetworkStatus:(NSString *)type{
  60. if (type == nil || type.length == 0) {
  61. return nil;
  62. }
  63. QNNetworkStatus *status = nil;
  64. @synchronized (self) {
  65. status = self.networkStatusInfo[type];
  66. }
  67. if (status == nil) {
  68. status = [[QNNetworkStatus alloc] init];
  69. }
  70. return status;
  71. }
  72. - (void)updateNetworkStatus:(NSString *)type speed:(int)speed{
  73. if (type == nil || type.length == 0) {
  74. return;
  75. }
  76. @synchronized (self) {
  77. QNNetworkStatus *status = self.networkStatusInfo[type];
  78. if (status == nil) {
  79. status = [[QNNetworkStatus alloc] init];
  80. self.networkStatusInfo[type] = status;
  81. }
  82. status.speed = speed;
  83. }
  84. [self asyncRecordNetworkStatusInfo];
  85. }
  86. // ----- status 持久化
  87. #define kNetworkStatusDiskKey @"NetworkStatus:v1.0.1"
  88. - (void)asyncRecordNetworkStatusInfo{
  89. @synchronized (self) {
  90. if (self.isHandlingNetworkInfoOfDisk) {
  91. return;
  92. }
  93. self.isHandlingNetworkInfoOfDisk = YES;
  94. }
  95. QNAsyncRun(^{
  96. [self recordNetworkStatusInfo];
  97. self.isHandlingNetworkInfoOfDisk = NO;
  98. });
  99. }
  100. - (void)asyncRecoverNetworkStatusFromDisk{
  101. @synchronized (self) {
  102. if (self.isHandlingNetworkInfoOfDisk) {
  103. return;
  104. }
  105. self.isHandlingNetworkInfoOfDisk = YES;
  106. }
  107. QNAsyncRun(^{
  108. [self recoverNetworkStatusFromDisk];
  109. self.isHandlingNetworkInfoOfDisk = NO;
  110. });
  111. }
  112. - (void)recordNetworkStatusInfo{
  113. if (self.recorder == nil || self.networkStatusInfo == nil) {
  114. return;
  115. }
  116. NSDictionary *networkStatusInfo = nil;
  117. @synchronized(self) {
  118. networkStatusInfo = [self.networkStatusInfo copy];
  119. }
  120. NSMutableDictionary *statusInfo = [NSMutableDictionary dictionary];
  121. for (NSString *key in networkStatusInfo.allKeys) {
  122. NSDictionary *statusDictionary = [networkStatusInfo[key] toDictionary];
  123. if (statusDictionary) {
  124. [statusInfo setObject:statusDictionary forKey:key];
  125. }
  126. }
  127. NSData *data = [NSJSONSerialization dataWithJSONObject:statusInfo options:NSJSONWritingPrettyPrinted error:nil];
  128. if (data) {
  129. [self.recorder set:kNetworkStatusDiskKey data:data];
  130. }
  131. }
  132. - (void)recoverNetworkStatusFromDisk{
  133. if (self.recorder == nil) {
  134. return;
  135. }
  136. NSData *data = [self.recorder get:kNetworkStatusDiskKey];
  137. if (data == nil) {
  138. return;
  139. }
  140. NSError *error = nil;
  141. NSDictionary *statusInfo = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
  142. if (error != nil || ![statusInfo isKindOfClass:[NSDictionary class]]) {
  143. [self.recorder del:kNetworkStatusDiskKey];
  144. return;
  145. }
  146. NSMutableDictionary *networkStatusInfo = [NSMutableDictionary dictionary];
  147. for (NSString *key in statusInfo.allKeys) {
  148. NSDictionary *value = statusInfo[key];
  149. QNNetworkStatus *status = [QNNetworkStatus statusFromDictionary:value];
  150. if (status) {
  151. [networkStatusInfo setObject:status forKey:key];
  152. }
  153. }
  154. @synchronized(self) {
  155. [self.networkStatusInfo setValuesForKeysWithDictionary:networkStatusInfo];
  156. }
  157. }
  158. @end