Определить, отображает ли SKStoreReviewController окно оценки приложения в macOS - PullRequest
0 голосов
/ 14 января 2019

Способ запроса отзыва

SKStoreReviewController.requestReview()

На iOS люди нашли довольно простой способ узнать, было ли представлено окно рейтинга ссылка (просто подсчитав количество окон в приложении)

Как надежно определить это в macOS? (Подсчет альтернатив windows?)

Store

1 Ответ

0 голосов
/ 14 января 2019

Обнаружено, что 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...