浏览代码

check App Extension in runtime to support App Extension target

ibireme 9 年之前
父节点
当前提交
7500348748
共有 4 个文件被更改,包括 55 次插入23 次删除
  1. 4 6
      README.md
  2. 6 1
      YYWebImage/YYWebImageManager.h
  3. 25 4
      YYWebImage/YYWebImageManager.m
  4. 20 12
      YYWebImage/YYWebImageOperation.m

+ 4 - 6
README.md

@@ -112,10 +112,9 @@ Installation
 	* MobileCoreServices
 	* MobileCoreServices
 	* sqlite3
 	* sqlite3
 	* libz
 	* libz
-4. Import `YYWebImage.h`.
+4. Add `Vendor/WebP.framework`(static library) to your Xcode project if you want to support WebP.
+5. Import `YYWebImage.h`.
 
 
-*  If you want to support WebP format, you may add Add `Vendor/WebP.framework`(static library) to your Xcode project.
-*  If you want to use it in App Extension, you may add `YY_TARGET_IS_EXTENSION` flag in `Build Settings` - `Preprocessor Macros` sections.
 
 
 Documentation
 Documentation
 ==============
 ==============
@@ -242,10 +241,9 @@ YYWebImage 是一个异步图片加载框架 ([YYKit](https://github.com/ibireme
 	* MobileCoreServices
 	* MobileCoreServices
 	* sqlite3
 	* sqlite3
 	* libz
 	* libz
-4. 导入 `YYWebImage.h`。
+4. 如果你需要支持 WebP,可以将 `Vendor/WebP.framework`(静态库) 加入你的工程。
+5. 导入 `YYWebImage.h`。
 
 
-*  如果你需要支持 WebP 格式,可以将 `Vendor/WebP.framework`(静态库) 加入你的工程。
-*  如果你需要在 App Extension 中使用这些代码, 可以在 `Build Settings` - `Preprocessor Macros` 中添加 `YY_TARGET_IS_EXTENSION` 参数。
 
 
 文档
 文档
 ==============
 ==============

+ 6 - 1
YYWebImage/YYWebImageManager.h

@@ -270,13 +270,14 @@ typedef void (^YYWebImageCompletionBlock)(UIImage *image, NSURL *url, YYWebImage
 - (NSString *)cacheKeyForURL:(NSURL *)url;
 - (NSString *)cacheKeyForURL:(NSURL *)url;
 
 
 
 
-
 /**
 /**
  Increments the number of active network requests.
  Increments the number of active network requests.
  If this number was zero before incrementing, this will start animating the
  If this number was zero before incrementing, this will start animating the
  status bar network activity indicator.
  status bar network activity indicator.
  
  
  This method is thread safe.
  This method is thread safe.
+ 
+ This method has no effect in App Extension.
  */
  */
 + (void)incrementNetworkActivityCount;
 + (void)incrementNetworkActivityCount;
 
 
@@ -286,6 +287,8 @@ typedef void (^YYWebImageCompletionBlock)(UIImage *image, NSURL *url, YYWebImage
  status bar network activity indicator.
  status bar network activity indicator.
  
  
  This method is thread safe.
  This method is thread safe.
+ 
+ This method has no effect in App Extension.
  */
  */
 + (void)decrementNetworkActivityCount;
 + (void)decrementNetworkActivityCount;
 
 
@@ -293,6 +296,8 @@ typedef void (^YYWebImageCompletionBlock)(UIImage *image, NSURL *url, YYWebImage
  Get current number of active network requests.
  Get current number of active network requests.
  
  
  This method is thread safe.
  This method is thread safe.
+ 
+ This method has no effect in App Extension.
  */
  */
 + (NSInteger)currentNetworkActivityCount;
 + (NSInteger)currentNetworkActivityCount;
 
 

+ 25 - 4
YYWebImage/YYWebImageManager.m

@@ -15,6 +15,24 @@
 #import <objc/runtime.h>
 #import <objc/runtime.h>
 
 
 #define kNetworkIndicatorDelay (1/30.0)
 #define kNetworkIndicatorDelay (1/30.0)
+
+
+/// Returns nil in App Extension.
+static UIApplication *_YYSharedApplication() {
+    static BOOL isAppExtension = NO;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        Class cls = NSClassFromString(@"UIApplication");
+        if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES;
+        if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES;
+    });
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
+    return isAppExtension ? nil : [UIApplication performSelector:@selector(sharedApplication)];
+#pragma clang diagnostic pop
+}
+
+
 @interface _YYUIApplicationNetworkIndicatorInfo : NSObject
 @interface _YYUIApplicationNetworkIndicatorInfo : NSObject
 @property (nonatomic, assign) NSInteger count;
 @property (nonatomic, assign) NSInteger count;
 @property (nonatomic, strong) NSTimer *timer;
 @property (nonatomic, strong) NSTimer *timer;
@@ -112,16 +130,19 @@
 }
 }
 
 
 + (void)_delaySetActivity:(NSTimer *)timer {
 + (void)_delaySetActivity:(NSTimer *)timer {
-#ifndef YY_TARGET_IS_EXTENSION
+    UIApplication *app = _YYSharedApplication();
+    if (!app) return;
+    
     NSNumber *visiable = timer.userInfo;
     NSNumber *visiable = timer.userInfo;
-    if ([UIApplication sharedApplication].networkActivityIndicatorVisible != visiable.boolValue) {
-        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:visiable.boolValue];
+    if (app.networkActivityIndicatorVisible != visiable.boolValue) {
+        [app setNetworkActivityIndicatorVisible:visiable.boolValue];
     }
     }
     [timer invalidate];
     [timer invalidate];
-#endif
 }
 }
 
 
 + (void)_changeNetworkActivityCount:(NSInteger)delta {
 + (void)_changeNetworkActivityCount:(NSInteger)delta {
+    if (!_YYSharedApplication()) return;
+    
     void (^block)() = ^{
     void (^block)() = ^{
         _YYUIApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo];
         _YYUIApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo];
         if (!info) {
         if (!info) {

+ 20 - 12
YYWebImage/YYWebImageOperation.m

@@ -27,6 +27,22 @@
 #define MIN_PROGRESSIVE_TIME_INTERVAL 0.2
 #define MIN_PROGRESSIVE_TIME_INTERVAL 0.2
 #define MIN_PROGRESSIVE_BLUR_TIME_INTERVAL 0.4
 #define MIN_PROGRESSIVE_BLUR_TIME_INTERVAL 0.4
 
 
+
+/// Returns nil in App Extension.
+static UIApplication *_YYSharedApplication() {
+    static BOOL isAppExtension = NO;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        Class cls = NSClassFromString(@"UIApplication");
+        if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES;
+        if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES;
+    });
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
+    return isAppExtension ? nil : [UIApplication performSelector:@selector(sharedApplication)];
+#pragma clang diagnostic pop
+}
+
 /// Returns YES if the right-bottom pixel is filled.
 /// Returns YES if the right-bottom pixel is filled.
 static BOOL YYCGImageLastPixelFilled(CGImageRef image) {
 static BOOL YYCGImageLastPixelFilled(CGImageRef image) {
     if (!image) return NO;
     if (!image) return NO;
@@ -262,22 +278,18 @@ static void URLInBlackListAdd(NSURL *url) {
 
 
 - (void)dealloc {
 - (void)dealloc {
     [_lock lock];
     [_lock lock];
-#ifndef YY_TARGET_IS_EXTENSION
     if (_taskID != UIBackgroundTaskInvalid) {
     if (_taskID != UIBackgroundTaskInvalid) {
-        [[UIApplication sharedApplication] endBackgroundTask:_taskID];
+        [_YYSharedApplication() endBackgroundTask:_taskID];
         _taskID = UIBackgroundTaskInvalid;
         _taskID = UIBackgroundTaskInvalid;
     }
     }
-#endif
     if ([self isExecuting]) {
     if ([self isExecuting]) {
         self.cancelled = YES;
         self.cancelled = YES;
         self.finished = YES;
         self.finished = YES;
         if (_connection) {
         if (_connection) {
             [_connection cancel];
             [_connection cancel];
-#ifndef YY_TARGET_IS_EXTENSION
             if (![_request.URL isFileURL] && (_options & YYWebImageOptionShowNetworkActivity)) {
             if (![_request.URL isFileURL] && (_options & YYWebImageOptionShowNetworkActivity)) {
                 [YYWebImageManager decrementNetworkActivityCount];
                 [YYWebImageManager decrementNetworkActivityCount];
             }
             }
-#endif
         }
         }
         if (_completion) {
         if (_completion) {
             @autoreleasepool {
             @autoreleasepool {
@@ -289,14 +301,12 @@ static void URLInBlackListAdd(NSURL *url) {
 }
 }
 
 
 - (void)_endBackgroundTask {
 - (void)_endBackgroundTask {
-#ifndef YY_TARGET_IS_EXTENSION
     [_lock lock];
     [_lock lock];
     if (_taskID != UIBackgroundTaskInvalid) {
     if (_taskID != UIBackgroundTaskInvalid) {
-        [[UIApplication sharedApplication] endBackgroundTask:_taskID];
+        [_YYSharedApplication() endBackgroundTask:_taskID];
         _taskID = UIBackgroundTaskInvalid;
         _taskID = UIBackgroundTaskInvalid;
     }
     }
     [_lock unlock];
     [_lock unlock];
-#endif
 }
 }
 
 
 #pragma mark - Runs in operation thread
 #pragma mark - Runs in operation thread
@@ -750,11 +760,10 @@ static void URLInBlackListAdd(NSURL *url) {
             } else {
             } else {
                 self.executing = YES;
                 self.executing = YES;
                 [self performSelector:@selector(_startOperation) onThread:[[self class] _networkThread] withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
                 [self performSelector:@selector(_startOperation) onThread:[[self class] _networkThread] withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
-#ifndef YY_TARGET_IS_EXTENSION
-                if (_options & YYWebImageOptionAllowBackgroundTask) {
+                if ((_options & YYWebImageOptionAllowBackgroundTask) && _YYSharedApplication()) {
                     __weak __typeof__ (self) _self = self;
                     __weak __typeof__ (self) _self = self;
                     if (_taskID == UIBackgroundTaskInvalid) {
                     if (_taskID == UIBackgroundTaskInvalid) {
-                        _taskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
+                        _taskID = [_YYSharedApplication() beginBackgroundTaskWithExpirationHandler:^{
                             __strong __typeof (_self) self = _self;
                             __strong __typeof (_self) self = _self;
                             if (self) {
                             if (self) {
                                 [self cancel];
                                 [self cancel];
@@ -763,7 +772,6 @@ static void URLInBlackListAdd(NSURL *url) {
                         }];
                         }];
                     }
                     }
                 }
                 }
-#endif
             }
             }
         }
         }
         [_lock unlock];
         [_lock unlock];