2

私は参加している小売店でバーコードをスキャンするための iOS アプリを作成しています。顧客が領収書に印刷された QR コードをスキャンした後、その場所が顧客に代わって慈善団体に寄付します。

ユーザーが参加している場所に 60 秒以上滞在した場合にローカル通知を送信して、そこで購入したレシートをスキャンするように促したいと考えています。

私の問題は、ユーザーが地域に入ったときに呼び出しを 60 秒遅らせたいということです.60 秒後にまだその地域にいる場合は、ローカル通知を送信します.アプリがフォアグラウンドに戻るまで起動します。これは、遅延が発生する前にスレッドが終了することがあることに関係していると思いますが、よくわかりません。stackoverflow や他の場所 (ブロック、nstimer など) で見つけることができるすべてのアプローチを試しましたが、役に立ちませんでした。この問題へのより良いアプローチ方法についてのアイデアはありますか?

- (void) sendLocalNotification:(NSString *)regionId {
NSLog(@"we entered %@ and we're currently in %@", regionId, self.currentRegionId);
if ([regionId isEqualToString:self.currentRegionId]) {// if we're still in the region, send a local notification
    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil) return;
    NSDate *fireTime = [[NSDate date] addTimeInterval:2]; // adds 2 secs
    localNotif.fireDate = fireTime;
    localNotif.alertBody = [NSString stringWithFormat:@"Did you just visit %@? If so, don't forget to scan your receipt!", regionId];
    localNotif.applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber+1;
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];
}
}

- (void) stillInRegion:(CLRegion *)region {

NSLog(@"did enter region: %@", region.identifier);

[self performSelector:@selector(sendLocalNotification:) withObject:region.identifier afterDelay:60];
}

- (void) locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
if (self.didLaunchForRegionUpdate) {
    NSString *path = [DGGeofencingHelper applicationDocumentsDirectory];
    NSString *finalPath = [path stringByAppendingPathComponent:@"notifications.dg"];
    NSMutableArray *updates = [NSMutableArray arrayWithContentsOfFile:finalPath];

    if (!updates) {
        updates = [NSMutableArray array];
    }

    NSMutableDictionary *update = [NSMutableDictionary dictionary];

    [update setObject:region.identifier forKey:@"fid"];
    [update setObject:[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] forKey:@"timestamp"];
    [update setObject:@"enter" forKey:@"status"];

    [updates addObject:update];

    [updates writeToFile:finalPath atomically:YES];
} else {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:@"enter" forKey:@"status"];
    [dict setObject:region.identifier forKey:@"fid"];
    NSString *jsStatement = [NSString stringWithFormat:@"DGGeofencing.regionMonitorUpdate(%@);", [dict JSONString]];
    [self.webView stringByEvaluatingJavaScriptFromString:jsStatement];
}
self.currentRegionId = region.identifier;
self.cRegionEnterTime =[NSDate date];
[self stillInRegion:region];
}
4

2 に答える 2

1

didEnterRegion メソッド内で、目的の結果を得るために次のコードを使用していました。

 UIApplication*   app = [UIApplication sharedApplication];
    bgTaskIdentifier = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTaskIdentifier];
        bgTaskIdentifier = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:180 target:self  selector:@selector(stillInRegion:) userInfo:region.identifier repeats:NO];

        [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];

        [[NSRunLoop currentRunLoop] run];
    });

@ lucaslt89 が持っていたものにかなり近いですが、わずかに異なります。

于 2013-06-21T18:10:28.433 に答える
1

locationManager:didEnterRegion がフォアグラウンドで呼び出され、アプリケーションがバックグラウンドに移行していますか? これらのメソッドをいつ呼び出すかについてはよくわかりませんが、次のようにバックグラウンド タスクを作成してみてください。

  1. たとえば、bgTaskIdentifier と呼ばれるタイプ NSUInteger のプロパティを追加して、バックグラウンド タスク識別子を格納します。
  2. [self stillInRegion:region]; への呼び出しの前に。次のコードを追加します。

    bgTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}];

  3. stillInRegion メソッドを呼び出す必要があり、バックグラウンドに移行しても続行されるため、遅延は引き続きカウントされます。最後に、バックグラウンド タスクを終了する必要があります。これを行うには、次の行を sendLocalNotification メソッドの最後の if ブロックの後に追加します。

    [[UIApplication sharedApplication] endBackgroundTask:bgTaskIdentifier];

それが役に立ったかどうか教えてください!私の下手な英語ですみません!

良い一日を過ごしてください!

于 2013-06-11T00:37:13.793 に答える