Committed by
GitHub
Fix Infinite loop on iOS (#156)
* [Fix][*]fix Infinite loop of iOS Signed-off-by: suyao-lingoace <yao.su@pplingo.com> * Fix Infinite loop on iOS When you use setter method in it's KVO,Will cause infinite loop,So I hook the setter method ,If the enable is 'YES' ,I ignore other call the setter. Signed-off-by: suyao-lingoace <yao.su@pplingo.com> * Update wakelock/ios/Classes/WakelockPlugin.m Co-authored-by: creativecreatorormaybenot <creativecreatorormaybenot@gmail.com> * Update wakelock/ios/Classes/WakelockPlugin.m Co-authored-by: creativecreatorormaybenot <creativecreatorormaybenot@gmail.com> * Update wakelock/ios/Classes/WakelockPlugin.m Co-authored-by: creativecreatorormaybenot <creativecreatorormaybenot@gmail.com>
Showing
7 changed files
with
95 additions
and
98 deletions
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | archiveVersion = 1; | 3 | archiveVersion = 1; |
| 4 | classes = { | 4 | classes = { |
| 5 | }; | 5 | }; |
| 6 | - objectVersion = 46; | 6 | + objectVersion = 50; |
| 7 | objects = { | 7 | objects = { |
| 8 | 8 | ||
| 9 | /* Begin PBXBuildFile section */ | 9 | /* Begin PBXBuildFile section */ |
| @@ -76,7 +76,6 @@ | @@ -76,7 +76,6 @@ | ||
| 76 | A3A052DAD735CA9CF9731DD7 /* Pods-Runner.release.xcconfig */, | 76 | A3A052DAD735CA9CF9731DD7 /* Pods-Runner.release.xcconfig */, |
| 77 | 06B046091A6718E60BC8F2E0 /* Pods-Runner.profile.xcconfig */, | 77 | 06B046091A6718E60BC8F2E0 /* Pods-Runner.profile.xcconfig */, |
| 78 | ); | 78 | ); |
| 79 | - name = Pods; | ||
| 80 | path = Pods; | 79 | path = Pods; |
| 81 | sourceTree = "<group>"; | 80 | sourceTree = "<group>"; |
| 82 | }; | 81 | }; |
| @@ -338,9 +337,13 @@ | @@ -338,9 +337,13 @@ | ||
| 338 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | 337 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 339 | CLANG_ENABLE_MODULES = YES; | 338 | CLANG_ENABLE_MODULES = YES; |
| 340 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 339 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
| 340 | + DEVELOPMENT_TEAM = ""; | ||
| 341 | ENABLE_BITCODE = NO; | 341 | ENABLE_BITCODE = NO; |
| 342 | INFOPLIST_FILE = Runner/Info.plist; | 342 | INFOPLIST_FILE = Runner/Info.plist; |
| 343 | - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | 343 | + LD_RUNPATH_SEARCH_PATHS = ( |
| 344 | + "$(inherited)", | ||
| 345 | + "@executable_path/Frameworks", | ||
| 346 | + ); | ||
| 344 | PRODUCT_BUNDLE_IDENTIFIER = creativemaybeno.wakelockExample; | 347 | PRODUCT_BUNDLE_IDENTIFIER = creativemaybeno.wakelockExample; |
| 345 | PRODUCT_NAME = "$(TARGET_NAME)"; | 348 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 346 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | 349 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
| @@ -449,7 +452,8 @@ | @@ -449,7 +452,8 @@ | ||
| 449 | MTL_ENABLE_DEBUG_INFO = NO; | 452 | MTL_ENABLE_DEBUG_INFO = NO; |
| 450 | SDKROOT = iphoneos; | 453 | SDKROOT = iphoneos; |
| 451 | SUPPORTED_PLATFORMS = iphoneos; | 454 | SUPPORTED_PLATFORMS = iphoneos; |
| 452 | - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; | 455 | + SWIFT_COMPILATION_MODE = wholemodule; |
| 456 | + SWIFT_OPTIMIZATION_LEVEL = "-O"; | ||
| 453 | TARGETED_DEVICE_FAMILY = "1,2"; | 457 | TARGETED_DEVICE_FAMILY = "1,2"; |
| 454 | VALIDATE_PRODUCT = YES; | 458 | VALIDATE_PRODUCT = YES; |
| 455 | }; | 459 | }; |
| @@ -462,9 +466,13 @@ | @@ -462,9 +466,13 @@ | ||
| 462 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 463 | CLANG_ENABLE_MODULES = YES; | 467 | CLANG_ENABLE_MODULES = YES; |
| 464 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 468 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
| 469 | + DEVELOPMENT_TEAM = ""; | ||
| 465 | ENABLE_BITCODE = NO; | 470 | ENABLE_BITCODE = NO; |
| 466 | INFOPLIST_FILE = Runner/Info.plist; | 471 | INFOPLIST_FILE = Runner/Info.plist; |
| 467 | - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | 472 | + LD_RUNPATH_SEARCH_PATHS = ( |
| 473 | + "$(inherited)", | ||
| 474 | + "@executable_path/Frameworks", | ||
| 475 | + ); | ||
| 468 | PRODUCT_BUNDLE_IDENTIFIER = creativemaybeno.wakelockExample; | 476 | PRODUCT_BUNDLE_IDENTIFIER = creativemaybeno.wakelockExample; |
| 469 | PRODUCT_NAME = "$(TARGET_NAME)"; | 477 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 470 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | 478 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
| @@ -481,9 +489,13 @@ | @@ -481,9 +489,13 @@ | ||
| 481 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | 489 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
| 482 | CLANG_ENABLE_MODULES = YES; | 490 | CLANG_ENABLE_MODULES = YES; |
| 483 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 491 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
| 492 | + DEVELOPMENT_TEAM = ""; | ||
| 484 | ENABLE_BITCODE = NO; | 493 | ENABLE_BITCODE = NO; |
| 485 | INFOPLIST_FILE = Runner/Info.plist; | 494 | INFOPLIST_FILE = Runner/Info.plist; |
| 486 | - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | 495 | + LD_RUNPATH_SEARCH_PATHS = ( |
| 496 | + "$(inherited)", | ||
| 497 | + "@executable_path/Frameworks", | ||
| 498 | + ); | ||
| 487 | PRODUCT_BUNDLE_IDENTIFIER = creativemaybeno.wakelockExample; | 499 | PRODUCT_BUNDLE_IDENTIFIER = creativemaybeno.wakelockExample; |
| 488 | PRODUCT_NAME = "$(TARGET_NAME)"; | 500 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 489 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | 501 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
| @@ -27,8 +27,6 @@ | @@ -27,8 +27,6 @@ | ||
| 27 | selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | 27 | selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
| 28 | selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | 28 | selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
| 29 | shouldUseLaunchSchemeArgsEnv = "YES"> | 29 | shouldUseLaunchSchemeArgsEnv = "YES"> |
| 30 | - <Testables> | ||
| 31 | - </Testables> | ||
| 32 | <MacroExpansion> | 30 | <MacroExpansion> |
| 33 | <BuildableReference | 31 | <BuildableReference |
| 34 | BuildableIdentifier = "primary" | 32 | BuildableIdentifier = "primary" |
| @@ -38,8 +36,8 @@ | @@ -38,8 +36,8 @@ | ||
| 38 | ReferencedContainer = "container:Runner.xcodeproj"> | 36 | ReferencedContainer = "container:Runner.xcodeproj"> |
| 39 | </BuildableReference> | 37 | </BuildableReference> |
| 40 | </MacroExpansion> | 38 | </MacroExpansion> |
| 41 | - <AdditionalOptions> | ||
| 42 | - </AdditionalOptions> | 39 | + <Testables> |
| 40 | + </Testables> | ||
| 43 | </TestAction> | 41 | </TestAction> |
| 44 | <LaunchAction | 42 | <LaunchAction |
| 45 | buildConfiguration = "Debug" | 43 | buildConfiguration = "Debug" |
| @@ -61,8 +59,6 @@ | @@ -61,8 +59,6 @@ | ||
| 61 | ReferencedContainer = "container:Runner.xcodeproj"> | 59 | ReferencedContainer = "container:Runner.xcodeproj"> |
| 62 | </BuildableReference> | 60 | </BuildableReference> |
| 63 | </BuildableProductRunnable> | 61 | </BuildableProductRunnable> |
| 64 | - <AdditionalOptions> | ||
| 65 | - </AdditionalOptions> | ||
| 66 | </LaunchAction> | 62 | </LaunchAction> |
| 67 | <ProfileAction | 63 | <ProfileAction |
| 68 | buildConfiguration = "Profile" | 64 | buildConfiguration = "Profile" |
| 1 | -#import <Foundation/Foundation.h> | ||
| 2 | - | ||
| 3 | -NS_ASSUME_NONNULL_BEGIN | ||
| 4 | - | ||
| 5 | -@interface IdleTimerDisabledObserver : NSObject | ||
| 6 | - | ||
| 7 | -@property BOOL enable; | ||
| 8 | - | ||
| 9 | -+ (IdleTimerDisabledObserver*)singleInstance; | ||
| 10 | - | ||
| 11 | -- (void) beginObserving; | ||
| 12 | - | ||
| 13 | -- (void) endObserving; | ||
| 14 | - | ||
| 15 | -@end | ||
| 16 | - | ||
| 17 | -NS_ASSUME_NONNULL_END |
| 1 | -#import "IdleTimerDisabledObserver.h" | ||
| 2 | - | ||
| 3 | -@interface IdleTimerDisabledObserver() { | ||
| 4 | - int numObservers; | ||
| 5 | -} | ||
| 6 | - | ||
| 7 | -@end | ||
| 8 | - | ||
| 9 | -static void * mKeyPathObserverContextApplicationIsIdleTimerDisabled = &mKeyPathObserverContextApplicationIsIdleTimerDisabled; | ||
| 10 | - | ||
| 11 | -@implementation IdleTimerDisabledObserver | ||
| 12 | - | ||
| 13 | -+ (IdleTimerDisabledObserver*)singleInstance { | ||
| 14 | - static IdleTimerDisabledObserver *instance = nil; | ||
| 15 | - static dispatch_once_t onceToken; | ||
| 16 | - dispatch_once(&onceToken, ^{ | ||
| 17 | - instance = [[self alloc] init]; | ||
| 18 | - }); | ||
| 19 | - return instance; | ||
| 20 | -} | ||
| 21 | - | ||
| 22 | -- (void)beginObserving { | ||
| 23 | - if (numObservers == 0) { | ||
| 24 | - [UIApplication.sharedApplication addObserver:self | ||
| 25 | - forKeyPath:@"idleTimerDisabled" | ||
| 26 | - options:NSKeyValueObservingOptionNew | ||
| 27 | - context:mKeyPathObserverContextApplicationIsIdleTimerDisabled]; | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - numObservers ++; | ||
| 31 | -} | ||
| 32 | - | ||
| 33 | -- (void)endObserving { | ||
| 34 | - numObservers --; | ||
| 35 | - | ||
| 36 | - if (numObservers == 0) { | ||
| 37 | - [UIApplication.sharedApplication removeObserver:self forKeyPath:@"idleTimerDisabled" context:mKeyPathObserverContextApplicationIsIdleTimerDisabled]; | ||
| 38 | - } | ||
| 39 | -} | ||
| 40 | - | ||
| 41 | -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { | ||
| 42 | - if (context == mKeyPathObserverContextApplicationIsIdleTimerDisabled) { | ||
| 43 | - if (UIApplication.sharedApplication.idleTimerDisabled != self.enable) { | ||
| 44 | - UIApplication.sharedApplication.idleTimerDisabled = self.enable; | ||
| 45 | - } | ||
| 46 | - } else { | ||
| 47 | - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; | ||
| 48 | - } | ||
| 49 | -} | ||
| 50 | - | ||
| 51 | - | ||
| 52 | -@end |
| 1 | +// | ||
| 2 | +// UIApplication+idleTimerLock.h | ||
| 3 | +// wakelock | ||
| 4 | +// | ||
| 5 | +// Created by suyao on 2021/12/17. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <UIKit/UIKit.h> | ||
| 9 | + | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | + | ||
| 12 | +@interface UIApplication (idleTimerLock) | ||
| 13 | + | ||
| 14 | +- (void)lock_idleTimerlockEnable:(BOOL)enable; | ||
| 15 | + | ||
| 16 | +@end | ||
| 17 | + | ||
| 18 | +NS_ASSUME_NONNULL_END |
| 1 | +// | ||
| 2 | +// UIApplication+idleTimerLock.m | ||
| 3 | +// wakelock | ||
| 4 | +// | ||
| 5 | +// Created by suyao on 2021/12/17. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "UIApplication+idleTimerLock.h" | ||
| 9 | +#import <objc/runtime.h> | ||
| 10 | + | ||
| 11 | +static NSString *idleTimerLockKey = @"idleTimerLockKey"; | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +@implementation UIApplication (idleTimerLock) | ||
| 15 | + | ||
| 16 | ++ (void)load { | ||
| 17 | + Method setIdleTimerDisabled = class_getInstanceMethod(self, @selector(setIdleTimerDisabled:)); | ||
| 18 | + | ||
| 19 | + Method lock_setIdleTimerDisabled = class_getInstanceMethod(self, @selector(lock_setIdleTimerDisabled:)); | ||
| 20 | + | ||
| 21 | + method_exchangeImplementations(setIdleTimerDisabled, lock_setIdleTimerDisabled); | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +- (void)lock_setIdleTimerDisabled:(BOOL)enable { | ||
| 25 | + if ([self lock_idleTimerlockEnable]) { | ||
| 26 | + return; | ||
| 27 | + } | ||
| 28 | + [self lock_setIdleTimerDisabled:enable]; | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +- (void)lock_idleTimerlockEnable:(BOOL)enable { | ||
| 32 | + objc_setAssociatedObject(self, &idleTimerLockKey, @(enable), OBJC_ASSOCIATION_COPY); | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +- (BOOL)lock_idleTimerlockEnable | ||
| 36 | +{ | ||
| 37 | + return [objc_getAssociatedObject(self, &idleTimerLockKey) boolValue]; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +@end |
| 1 | #import "WakelockPlugin.h" | 1 | #import "WakelockPlugin.h" |
| 2 | -#import "IdleTimerDisabledObserver.h" | ||
| 3 | #import "messages.h" | 2 | #import "messages.h" |
| 3 | +#import "UIApplication+idleTimerLock.h" | ||
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | @interface WakelockPlugin () <FLTWakelockApi> | 6 | @interface WakelockPlugin () <FLTWakelockApi> |
| @@ -13,37 +13,37 @@ | @@ -13,37 +13,37 @@ | ||
| 13 | + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { | 13 | + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { |
| 14 | WakelockPlugin* instance = [[WakelockPlugin alloc] init]; | 14 | WakelockPlugin* instance = [[WakelockPlugin alloc] init]; |
| 15 | FLTWakelockApiSetup(registrar.messenger, instance); | 15 | FLTWakelockApiSetup(registrar.messenger, instance); |
| 16 | - | ||
| 17 | - [[IdleTimerDisabledObserver singleInstance] beginObserving]; | ||
| 18 | } | 16 | } |
| 19 | 17 | ||
| 20 | - (void)toggleMsg:(FLTToggleMessage*)input error:(FlutterError**)error { | 18 | - (void)toggleMsg:(FLTToggleMessage*)input error:(FlutterError**)error { |
| 21 | - NSNumber *enable = input.enable; | ||
| 22 | - self.enable = enable.boolValue; | ||
| 23 | - NSNumber *enabled = [NSNumber numberWithBool:[[UIApplication sharedApplication] isIdleTimerDisabled]]; | ||
| 24 | - | ||
| 25 | - if (![enable isEqualToNumber:enabled]) { | ||
| 26 | - [[UIApplication sharedApplication] setIdleTimerDisabled:enable.boolValue]; | 19 | + BOOL enable = [input.enable boolValue]; |
| 20 | + if (!enable) { | ||
| 21 | + [[UIApplication sharedApplication] lock_idleTimerlockEnable:enable];//should disable first | ||
| 22 | + [self setIdleTimerDisabled:enable]; | ||
| 23 | + } else { | ||
| 24 | + [self setIdleTimerDisabled:enable]; | ||
| 25 | + [[UIApplication sharedApplication] lock_idleTimerlockEnable:enable]; | ||
| 26 | + } | ||
| 27 | + self.enable = enable; | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +- (void)setIdleTimerDisabled:(BOOL)enable { | ||
| 31 | + BOOL enabled = [[UIApplication sharedApplication] isIdleTimerDisabled]; | ||
| 32 | + if (enable!= enabled) { | ||
| 33 | + [[UIApplication sharedApplication] setIdleTimerDisabled:enable]; | ||
| 27 | } | 34 | } |
| 28 | } | 35 | } |
| 29 | 36 | ||
| 37 | + | ||
| 30 | - (FLTIsEnabledMessage*)isEnabledWithError:(FlutterError* __autoreleasing *)error { | 38 | - (FLTIsEnabledMessage*)isEnabledWithError:(FlutterError* __autoreleasing *)error { |
| 31 | NSNumber *enabled = [NSNumber numberWithBool:[[UIApplication sharedApplication] isIdleTimerDisabled]]; | 39 | NSNumber *enabled = [NSNumber numberWithBool:[[UIApplication sharedApplication] isIdleTimerDisabled]]; |
| 32 | - | ||
| 33 | FLTIsEnabledMessage* result = [[FLTIsEnabledMessage alloc] init]; | 40 | FLTIsEnabledMessage* result = [[FLTIsEnabledMessage alloc] init]; |
| 34 | result.enabled = enabled; | 41 | result.enabled = enabled; |
| 35 | - | ||
| 36 | return result; | 42 | return result; |
| 37 | } | 43 | } |
| 38 | 44 | ||
| 39 | - (void)setEnable:(BOOL)enable { | 45 | - (void)setEnable:(BOOL)enable { |
| 40 | - [IdleTimerDisabledObserver singleInstance].enable = enable; | ||
| 41 | - | ||
| 42 | _enable = enable; | 46 | _enable = enable; |
| 43 | } | 47 | } |
| 44 | 48 | ||
| 45 | -- (void)dealloc { | ||
| 46 | - [[IdleTimerDisabledObserver singleInstance] endObserving]; | ||
| 47 | -} | ||
| 48 | - | ||
| 49 | @end | 49 | @end |
-
Please register or login to post a comment