| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- //
- // RAUploadManager.m
- // test_autolayout
- //
- // Created by Ray on 02/05/2017.
- // Copyright © 2017 USAI. All rights reserved.
- //
- #import <UIKit/UIKit.h>
- #import "RAUploadManager.h"
- #import "NetworkUtils.h"
- #import "RAUtils.h"
- #import "UploadSettingController.h"
- @implementation RAUploadManager
- /*!
- * Called by Reachability whenever status changes.
- */
- - (void) reachabilityChanged:(NSNotification *)note
- {
- [self handleReachability:self.reach];
- }
- - (void)handleReachability:(Reachability *)reachability {
-
- NetworkStatus netStatus = [reachability currentReachabilityStatus];
-
- if (self.onlyWiFi && netStatus != ReachableViaWiFi) {
- DebugLog(@"not wifi & stop task");
- [self stopAllTasks];
- }
- }
- - (instancetype)init {
- if (self = [super init]) {
-
-
- /*
- Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the method reachabilityChanged will be called.
- */
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
-
- NSString *remoteHostName = @"www.apple.com";
- self.reach = [Reachability reachabilityWithHostName:remoteHostName];
- [self.reach startNotifier];
- [self handleReachability:self.reach];
-
- self.queue_status = QueueStatusDefault;
-
-
-
- NSDictionary *param = [[NSUserDefaults standardUserDefaults] objectForKey:kUploadSetting];
- if (param) {
- BOOL autoUpload = [[param objectForKey:@"auto_upload"] boolValue];
- BOOL autoRmFinish = [[param objectForKey:@"auto_rm_finish"] boolValue];
- BOOL autoRmErr = [[param objectForKey:@"auto_rm_error"] boolValue];
- BOOL onlyWiFi = [[param objectForKey:@"only_wifi"] boolValue];
- int retryCount = [[param objectForKey:@"retry_count"] intValue];
- self.autoStart = autoUpload;
- self.removeFinish = autoRmFinish;
- self.removeError = autoRmErr;
- self.maxRetry = retryCount;
- self.onlyWiFi = onlyWiFi;
- } else {
- self.autoStart = YES;
- self.removeFinish = YES;
- self.removeError = NO;
- self.maxRetry = 2;
- self.onlyWiFi = YES;
- }
-
-
- self.newtaskStatus = TaskStatusWait;
- self.maxThread = 3;
- // self.autoStart = true;
- // self.removeError=true;
- // self.removeFinish = true;
-
- self.operation_queue = [NSOperationQueue new];
- self.operation_queue.maxConcurrentOperationCount = self.maxThread;
-
-
- [self.operation_queue addObserver:self
- forKeyPath:@"operationCount"
- options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
- context:@"queueFinished changed"];
-
-
- //load task 要在监听arr_queue之前
- [self loadTasks];
-
-
- [self addObserver:self
- forKeyPath:@"arr_queue"
- options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
- context:@"arr_queue changed"];
- // self.arr_queue_lock = [NSLock new];
-
- // [self.arr_queue_lock lock];
- // [self.arr_queue_lock lock];
- // [self.arr_queue_lock unlock];
- // [self.arr_queue_lock unlock];
-
-
- // self.backgroundColor = [UIColor clearColor];
- }
- return self;
- }
- -(void) dealloc
- {
- [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
- [self.operation_queue removeObserver:self forKeyPath:@"operationCount"];
- [self.operation_queue removeObserver:self forKeyPath:@"arr_queue"];
- }
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- {
-
- if([keyPath isEqualToString:@"operationCount"])
- {
- if([[change objectForKey:NSKeyValueChangeNewKey] intValue]==0)
- {
- for(NSMutableDictionary* task in self.arr_queue)
- {
- if([task[@"status"] intValue] == TaskStatusError)
- {
- self.queue_status = QueueStatusFinishWithError;
- return;
- }
- }
- self.queue_status = QueueStatusFinish;
- }
- }
- if([keyPath isEqualToString:@"arr_queue"])
- {
- NSArray* newqueue=[change objectForKey:NSKeyValueChangeNewKey];
- NSArray* oldqueue=[change objectForKey:NSKeyValueChangeOldKey];
- if([newqueue isKindOfClass:[NSNull class]])
- newqueue=nil;
- if([oldqueue isKindOfClass:[NSNull class]])
- oldqueue=nil;
- if(newqueue.count>oldqueue.count)
- {
- self.queue_status = QueueStatusAdd;
- return;
- }
- }
-
- }
- //-(void) upload:(NSString*) url
- //{
- // while(self.activeThread<self.maxThread)
- // {
- // bool nomore=false;
- // for(int i=0;i<self.arr_queue.count;i++)
- // {
- // NSMutableDictionary* task = self.arr_queue[i];
- //
- // TaskStatus ts=[task[@"status"] intValue];
- // if (ts==TaskStatusWait) {
- // self.activeThread--;
- // [self uploadTask:task url:url];
- // break;
- // }
- // if(i==self.arr_queue.count-1)
- // nomore=true;
- //
- // }
- // if(nomore)
- // break;
- // }
- //}
- -(void) addTask:(NSMutableDictionary*) task
- {
-
- // [self.arr_queue addObject:task];
-
- // [self.arr_queue_lock lock];
- // [[self mutableArrayValueForKey:@"arr_queue"] addObject:task];
- // [self.arr_queue_lock unlock];
-
- @synchronized(self) {
- [[self mutableArrayValueForKey:@"arr_queue"] addObject:task];
- }
-
- if(self.newtaskStatus==TaskStatusWait)
- {
-
- [self startTask:task];
-
- }
- // self.queue_status = QueueStatusAdd;
-
- }
- -(void) addTasks:(NSMutableArray*) tasks
- {
- // [self.arr_queue_lock lock];
- // [[self mutableArrayValueForKey:@"arr_queue"] addObjectsFromArray:tasks];
- // [self.arr_queue_lock unlock];
-
- @synchronized(self) {
- // [[self mutableArrayValueForKey:@"arr_queue"] addObjectsFromArray:tasks];
-
-
- NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange([self mutableArrayValueForKey:@"arr_queue"].count,tasks.count )];
- [[self mutableArrayValueForKey:@"arr_queue"] insertObjects:tasks atIndexes:indexSet];
- }
-
- if(self.newtaskStatus==TaskStatusWait)
- {
- for(NSMutableDictionary* task in tasks)
- [self startTask:task];
-
-
- }
-
- // self.queue_status = QueueStatusAdd;
- }
- -(void) removeTasks:(NSMutableArray*) tasks
- {
-
- NSFileManager* fmanager = [NSFileManager new];
- for(NSMutableDictionary* task in tasks)
- {
-
- [self stopTask:task];
- NSError* error = nil;
- bool bdel=[fmanager removeItemAtPath:[self filePath:task] error:&error];
- if(!bdel)
- DebugLog(@"file delete failed path:%@",[self filePath:task]);
- }
-
-
-
- // [self.arr_queue_lock lock];
- // [[self mutableArrayValueForKey:@"arr_queue"] removeObjectsInArray:tasks];
- // [self.arr_queue_lock unlock];
-
- @synchronized(self) {
- // [[self mutableArrayValueForKey:@"arr_queue"] removeObjectsInArray:tasks];
-
- // NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange([self mutableArrayValueForKey:@"arr_queue"].count,tasks.count )];
-
- NSIndexSet *indexSet = [self.arr_queue indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
- {
- return [tasks containsObject:obj];
- // return [tasks indexOfObject:obj];
- }];
- // [NSIndexSet new];
- // for(NSMutableDictionary* task in tasks)
- // {
- //
- // [self.arr_queue indexOfObject:task];
- // indexSet set
- // }
-
- [[self mutableArrayValueForKey:@"arr_queue"] removeObjectsAtIndexes:indexSet];
- // -removeObjectFrom<Key>AtIndex
- // [ insertObjects:tasks atIndexes:indexSet];
- }
-
- // if (self.delegate && [self.delegate respondsToSelector:@selector(uploadManager:didRemoveTasks:)]) {
- // [self.delegate uploadManager:self didRemoveTasks:tasks];
- // }
- }
- -(void) removeTask:(NSMutableDictionary*) task
- {
- NSFileManager* fmanager = [NSFileManager new];
- // [self.arr_queue addObject:task];
- [self stopTask:task];
- NSError* error = nil;
- bool bdel=[fmanager removeItemAtPath:[self filePath:task] error:&error];
- if(!bdel)
- DebugLog(@"file delete failed path:%@",[self filePath:task]);
-
- // [self.arr_queue_lock lock];
- // DebugLog(@"lock");
- // [[self mutableArrayValueForKey:@"arr_queue"] removeObject:task];
- // DebugLog(@"unlock");
- // [self.arr_queue_lock unlock];
- // [self.arr_queue_lock lock];
- // [[self mutableArrayValueForKey:@"arr_queue"] removeObject:task];
- // [self.arr_queue_lock unlock];
-
-
- @synchronized(self) {
- [[self mutableArrayValueForKey:@"arr_queue"] removeObject:task];
- }
- // if (self.delegate && [self.delegate respondsToSelector:@selector(uploadManager:didRemoveTasks:)]) {
- // [self.delegate uploadManager:self didRemoveTasks:@[task]];
- // }
-
-
- }
- -(NSString*)filePath:(NSMutableDictionary*)task
- {
-
- NSString *path = [RAUtils appCacheDirectory];
- path= [path stringByAppendingPathComponent:task[@"path"]];
- path= [path stringByAppendingPathComponent:task[@"file"]];
- return path;
- }
- -(void) saveTasks
- {
- NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
- [defaults setObject:self.arr_queue forKey:@"upload_queue"];
- [defaults synchronize];
- }
- -(void) loadTasks
- {
- [self stopAllTasks];
- self.arr_queue = [NSMutableArray new];
- NSMutableArray* arr = [[[NSUserDefaults standardUserDefaults] objectForKey:@"upload_queue"] mutableCopy];
- // if(arr==nil)
-
-
- for(NSDictionary* task in arr)
- {
- NSMutableDictionary* newtask =[task mutableCopy];
- [self.arr_queue addObject:newtask];
- if(self.autoStart&&[task[@"status"] intValue]!=TaskStatusError&&[task[@"status"] intValue]!=TaskStatusFinish)
- [self startTask:newtask];
- }
-
- // NSDictionary* ddd = arr[0] ;
- // NSMutableDictionary* eee = [ddd mutableCopy];
- //
- // eee=[NSMutableDictionary dictionaryWithDictionary:ddd];
- // if(arr!=nil)
- // self.arr_queue=arr;
- // else
- // self.arr_queue= [[NSMutableArray alloc] init];
- //
- // for(__strong NSMutableDictionary* task in arr)
- // {
- //
- // task=[NSMutableDictionary dictionaryWithDictionary:task];
- //// if([task[@"status"] intValue]==TaskStatusStart)
- //// task[@"status"]=[NSNumber numberWithInteger:TaskStatusWait];
- // // NSMutableDictionary *new_task = [task mutableCopy];
- // if(self.autoStart&&[task[@"status"] intValue]!=TaskStatusError&&[task[@"status"] intValue]!=TaskStatusFinish)
- // [self startTask:task];
- // }
-
-
- }
- -(void) stopAllTasks
- {
- for(NSMutableDictionary* task in self.arr_queue)
- {
-
- [self stopTask:task];
- }
-
- }
- -(void) stopTask:(NSMutableDictionary*) task
- {
-
- if([task[@"status"] intValue]!=TaskStatusStart&&[task[@"status"] intValue]!=TaskStatusWait)
- {
- task[@"operation"]=nil;
- return; // task 已停止,返回
- }
-
- DebugLog(@"stop task");
- RAUploadOperation* operation = task[@"operation"];
- [operation cancel];
- task[@"operation"]=nil;
- task[@"status"] = [NSNumber numberWithInt:TaskStatusStop] ;
- task[@"progress"] = [NSNumber numberWithDouble:0.0];
-
-
- }
- -(void) startAllTasks
- {
-
- for(NSMutableDictionary* task in self.arr_queue)
- [self startTask:task];
- }
- -(void) startTask:(NSMutableDictionary*) task
- {
- if (self.onlyWiFi && self.reach.currentReachabilityStatus != ReachableViaWiFi) {
- return;
- }
- /*__block*/ NSMutableDictionary* block_task = task;
- __weak typeof(self) weakSelf = self;
- if([task[@"status"] intValue]==TaskStatusStart||[task[@"status"] intValue]==TaskStatusWait)
- return; // task 已在执行队列,返回
-
- RAUploadOperation* operation = [[RAUploadOperation alloc] initWithTaskinfo:task retry:self.maxRetry];
- [operation setCompletionBlock:^{
- switch ([block_task[@"status"] intValue]) {
- case TaskStatusFinish:
- {
- if(weakSelf.removeFinish)
- [self removeTask:block_task];
- }
- break;
- case TaskStatusError:
- {
- if(weakSelf.removeError)
- [self removeTask:block_task];
- }
- break;
- default:
- break;
- }
-
- }];
- task[@"msg"] = nil;
- task[@"operation"] = operation;
- task[@"status"] = [NSNumber numberWithInt:self.newtaskStatus] ;
- [self.operation_queue addOperation:operation];
-
-
- }
- //- (void) uploadTask:(NSMutableDictionary*) task url:(NSString*)url{
- //
- //// __weak typeof(self) weakself = self;
- //
- //
- //
- //
- //}
- - (BOOL)canUpload {
- if (self.onlyWiFi && self.reach.currentReachabilityStatus != ReachableViaWiFi) {
- return NO;
- }
- return YES;
- }
- @end
|