Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 离线游戏中心iOS成就_Objective C_Ios_Game Center_Achievements - Fatal编程技术网

Objective c 离线游戏中心iOS成就

Objective c 离线游戏中心iOS成就,objective-c,ios,game-center,achievements,Objective C,Ios,Game Center,Achievements,试图找出在离线模式下(例如,飞机模式打开)在游戏中心处理成就的最佳方式 据我所知,iOS 5+游戏中心负责离线提交的成绩和分数。它就像一个代理缓存,并在用户下次在线时将其提交到在线游戏中心。考虑到这一点,我会这样做: 在用户身份验证成功时,我加载成就并将其存储在字典中 [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *gcAchievments, NSError *error) { if (error) { .

试图找出在离线模式下(例如,飞机模式打开)在游戏中心处理成就的最佳方式

据我所知,iOS 5+游戏中心负责离线提交的成绩和分数。它就像一个代理缓存,并在用户下次在线时将其提交到在线游戏中心。考虑到这一点,我会这样做:

用户身份验证成功时,我加载成就并将其存储在字典中

[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *gcAchievments, NSError *error)
{
    if (error) { ..skipped ..}
    //This dictionary will store current achievments, so that we didn't submit them
    //once more and didn't show notification.
    achievments = [[NSMutableDictionary alloc] initWithCapacity:gcAchievments.count];

    //Storing achievments in dictionary
    for(GKAchievement *a in gcAchievments)
        [achievments setObject:a forKey:a.identifier];       
}];
稍后,当我提交新的成就时,我会在字典中检查成就,如果成就已经完成,就不提交。如果我提交了成就,我也会将其添加到
成就
字典(内存中),以立即反映该成就已经提交

GKAchievement *cachedAchievment = [achievments objectForKey:identifier];
if (cachedAchievment && cachedAchievment.percentComplete >= 100)
{
    //Already unlocked this achievment.
    return;
}

GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier: identifier];
if (achievement)
{
    achievement.percentComplete = percent;
    [achievement reportAchievementWithCompletionHandler:^(NSError *error)
     {
         if (!error)
         {
             //Flagging achievment as completed locally to avoid achieving it second time and showing notification.
             [achievments setObject:achievement forKey:achievement.identifier];

             //Now shoing notification banner.
             GKAchievementDescription * desc = [achievmentsDescriptions objectForKey:achievement.identifier];
             [[GKAchievementHandler defaultHandler] notifyAchievement:desc];
         }
         else
         {
             NSLog(@"Error in reporting achievements: %@", error);
         }
     }];
}
这种方法允许我在游戏代码中触发提交,而不用担心我会提交两次成就或显示两次通知横幅

当游戏中心在线时,一切正常。但如果我离线,我有两个问题

  • 加载代码会返回错误,
    成就的初始字典
    中没有填充已完成的成就,这意味着每次用户启动游戏时,他/她都会再次收到每个成就的通知横幅,即使该成就已获得奖励。然后,当它被放入字典后,它就不会显示,但我不想在每个游戏开始时显示一次成就

  • 我不确定离线提交的成就是否会在用户在线时到达游戏中心。我可以使用持久性存储(如数据库)来解决问题#1,以存储游戏启动之间的成就状态,但我是否应该在游戏中心联机时重新提交这些状态,以及如何检测游戏中心是否实际联机,因为即使脱机
    ReportAchievementTwithCompletionHandler
    也不会出错,因此,我无法检测它是否未提交。这是我测试的方式,我打开了飞行模式,解锁了一些成就,然后关闭了飞行模式,成就无法到达游戏中心,尽管这可能是“沙箱”问题


  • 为您提到的“成就解锁”添加持久存储,并为每个成就存储“成功提交到游戏中心”标志。然后,在线时,在启动时定期检查
    loadAchievementsWithCompletionHandler
    的结果,以查看
    解锁的每个成就是否都是&&!提交的
    实际上已经到达游戏中心,如果没有,请重新提交。

    嘿,你知道成就的表现吗?