Procházet zdrojové kódy

check App Extension in runtime to support App Extension target

ibireme před 9 roky
rodič
revize
7500348748

+ 4 - 6
README.md

@@ -112,10 +112,9 @@ Installation
 	* MobileCoreServices
 	* sqlite3
 	* 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
 ==============
@@ -242,10 +241,9 @@ YYWebImage 是一个异步图片加载框架 ([YYKit](https://github.com/ibireme
 	* MobileCoreServices
 	* sqlite3
 	* 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;
 
 
-
 /**
  Increments the number of active network requests.
  If this number was zero before incrementing, this will start animating the
  status bar network activity indicator.
  
  This method is thread safe.
+ 
+ This method has no effect in App Extension.
  */
 + (void)incrementNetworkActivityCount;
 
@@ -286,6 +287,8 @@ typedef void (^YYWebImageCompletionBlock)(UIImage *image, NSURL *url, YYWebImage
  status bar network activity indicator.
  
  This method is thread safe.
+ 
+ This method has no effect in App Extension.
  */
 + (void)decrementNetworkActivityCount;
 
@@ -293,6 +296,8 @@ typedef void (^YYWebImageCompletionBlock)(UIImage *image, NSURL *url, YYWebImage
  Get current number of active network requests.
  
  This method is thread safe.
+ 
+ This method has no effect in App Extension.
  */
 + (NSInteger)currentNetworkActivityCount;
 

+ 25 - 4
YYWebImage/YYWebImageManager.m

@@ -15,6 +15,24 @@
 #import <objc/runtime.h>
 
 #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
 @property (nonatomic, assign) NSInteger count;
 @property (nonatomic, strong) NSTimer *timer;
@@ -112,16 +130,19 @@
 }
 
 + (void)_delaySetActivity:(NSTimer *)timer {
-#ifndef YY_TARGET_IS_EXTENSION
+    UIApplication *app = _YYSharedApplication();
+    if (!app) return;
+    
     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];
-#endif
 }
 
 + (void)_changeNetworkActivityCount:(NSInteger)delta {
+    if (!_YYSharedApplication()) return;
+    
     void (^block)() = ^{
         _YYUIApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo];
         if (!info) {

+ 20 - 12
YYWebImage/YYWebImageOperation.m

@@ -27,6 +27,22 @@
 #define MIN_PROGRESSIVE_TIME_INTERVAL 0.2
 #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.
 static BOOL YYCGImageLastPixelFilled(CGImageRef image) {
     if (!image) return NO;
@@ -262,22 +278,18 @@ static void URLInBlackListAdd(NSURL *url) {
 
 - (void)dealloc {
     [_lock lock];
-#ifndef YY_TARGET_IS_EXTENSION
     if (_taskID != UIBackgroundTaskInvalid) {
-        [[UIApplication sharedApplication] endBackgroundTask:_taskID];
+        [_YYSharedApplication() endBackgroundTask:_taskID];
         _taskID = UIBackgroundTaskInvalid;
     }
-#endif
     if ([self isExecuting]) {
         self.cancelled = YES;
         self.finished = YES;
         if (_connection) {
             [_connection cancel];
-#ifndef YY_TARGET_IS_EXTENSION
             if (![_request.URL isFileURL] && (_options & YYWebImageOptionShowNetworkActivity)) {
                 [YYWebImageManager decrementNetworkActivityCount];
             }
-#endif
         }
         if (_completion) {
             @autoreleasepool {
@@ -289,14 +301,12 @@ static void URLInBlackListAdd(NSURL *url) {
 }
 
 - (void)_endBackgroundTask {
-#ifndef YY_TARGET_IS_EXTENSION
     [_lock lock];
     if (_taskID != UIBackgroundTaskInvalid) {
-        [[UIApplication sharedApplication] endBackgroundTask:_taskID];
+        [_YYSharedApplication() endBackgroundTask:_taskID];
         _taskID = UIBackgroundTaskInvalid;
     }
     [_lock unlock];
-#endif
 }
 
 #pragma mark - Runs in operation thread
@@ -750,11 +760,10 @@ static void URLInBlackListAdd(NSURL *url) {
             } else {
                 self.executing = YES;
                 [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;
                     if (_taskID == UIBackgroundTaskInvalid) {
-                        _taskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
+                        _taskID = [_YYSharedApplication() beginBackgroundTaskWithExpirationHandler:^{
                             __strong __typeof (_self) self = _self;
                             if (self) {
                                 [self cancel];
@@ -763,7 +772,6 @@ static void URLInBlackListAdd(NSURL *url) {
                         }];
                     }
                 }
-#endif
             }
         }
         [_lock unlock];