代码之家  ›  专栏  ›  技术社区  ›  Marek H

检测SKStoreReviewController是否在macOS上显示应用程序分级窗口

  •  1
  • Marek H  · 技术社区  · 7 年前

    请求复查的方法

    SKStoreReviewController.requestReview()
    

    在iOS上,人们找到了一个非常简单的方法来确定是否已经出现了评级窗口 link (只需计算应用程序中的窗口数)

    如何在macOS上可靠地检测到这一点(计算窗口选项?)

    Store

    1 回复  |  直到 7 年前
        1
  •  3
  •   Marek H    7 年前

    我发现了 CGWindowListCopyWindowInfo +NSRunningApplication是正确的检查对象:

    dispatch_time_t twoSecondsFromNow = DISPATCH_TIME_NOW + 2.0;
    dispatch_after(twoSecondsFromNow, dispatch_get_main_queue(), ^{
    
        //HERE REQUEST REVIEW
        [SKStoreReviewController requestReview];
    
        dispatch_time_t secondFromNow = DISPATCH_TIME_NOW + 1.0;
        dispatch_after(secondFromNow, dispatch_get_main_queue(), ^{
            CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
            NSArray <NSString*>*windowNames = [(__bridge NSArray *)windowList valueForKey:@"kCGWindowOwnerName"];
            CFRelease(windowList);
            if ([windowNames containsObject:@"storeuid"]) {
    
                //REPORT TO PREFERENCES THAT WE SUCCESSFULLY ASKED FOR REVIEW
                NSLog(@"Rating Window was presented");
            }
        });
    });
    

    可能的替代方案(自10.14.2起,失活延迟严重):

    - (void)findRunningApplication
    {
        NSArray<NSRunningApplication *> *runningApplications = [[NSWorkspace sharedWorkspace] runningApplications];
        for (NSRunningApplication *app in runningApplications) {
            if ([[app bundleIdentifier] isEqualToString:@"com.apple.storeuid"]) {
                [self setRunningApplication:app];
            }
        }
    }
    
    - (void)setRunningApplication:(NSRunningApplication *)runningApplication
    {
        if (runningApplication != _runningApplication) {
    
            if (runningApplication == nil) {
                [_runningApplication removeObserver:self forKeyPath:@"active"];
            } else {
                [runningApplication addObserver:self forKeyPath:@"active" options:NSKeyValueObservingOptionNew context:StoreInspectorKVOContext];
            }
            _runningApplication = runningApplication;
        }
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        if (context == StoreInspectorKVOContext) {
            if (object == [self runningApplication] && [keyPath isEqualToString:@"active"]) {
                [self runningApplicationActiveHasChanged];
            }
        } else {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    

    甚至可以从cgwindow中获得用户单击全局监视器事件+位置的评级

    NSEvent *monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSEventMaskLeftMouseDown)
                                                              handler:^(NSEvent *event) {
                                                                  NSLog(@"%@",event);
                                                              }];
    
    
    
    2019-01-13 23:58:12.727979+0100 testWindows2[11466:620853] NSEvent: type=LMouseDown loc=(994.746,172.551) time=103867.3 flags=0 win=0x0 winNum=4852 ctxt=0x0 evNum=9320 click=1 buttonNumber=0 pressure=1 deviceID:0x300000014400000 subtype=NSEventSubtypeTouch
    2019-01-13 23:58:12.729521+0100 testWindows2[11466:620853] {
        kCGWindowAlpha = 1;
        kCGWindowBounds =     {
            Height = 157;
            Width = 420;
            X = 786;
            Y = 23;
        };
        kCGWindowIsOnscreen = 1;
        kCGWindowLayer = 0;
        kCGWindowMemoryUsage = 1248;
        kCGWindowNumber = 4590;
        kCGWindowOwnerName = storeuid;
        kCGWindowOwnerPID = 7017;
        kCGWindowSharingState = 1;
        kCGWindowStoreType = 1;
    }
    
    推荐文章