1

社内のエンタープライズアプリの更新メソッドを作成しています。私が作成しようとしているのは、アプリにすばやく配置できるクラスであり、更新が必要かどうかをサーバーに確認します。これは私がこれまでに持っているものであり、正しくチェックしますがNO、メソッドを終了する前に戻ります。

私のcheckUpdate.hで

@interface checkForUpdate : NSObject

+ (BOOL)updateCheck;


@end

私のcheckUpdate.mで

#import "checkForUpdate.h"

@implementation checkForUpdate

BOOL needsUpdate
NSDictionary *versionDict;


#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)


+ (BOOL)updateCheck {

    NSString *urlStringVersion = [[NSString alloc] initWithFormat:@"http://URL/app_info?app=app"];
    NSURL *urlVersion = [NSURL URLWithString:urlStringVersion];

    dispatch_async(kBgQueue, ^{
        NSData* data =[NSData dataWithContentsOfURL:urlVersion];

        if (data){
            NSError* error;
            NSArray* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
            if (json != nil && [json count] != 0) {
                versionDict = [json objectAtIndex:0];

                CGFloat serverVersion = [[versionDict valueForKey:@"version"]floatValue];
                CGFloat appVersion = [[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey] floatValue];
                NSLog(@"Server Version %f",serverVersion);
                NSLog(@"App Version %f",appVersion);

                if ([versionDict count] != 0){
                    if (serverVersion > appVersion){
                        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
                        needsUpdate = YES;
                    }else{
                        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
                        needsUpdate = NO;
                    }
                }

            }
        }

    });

    return needsUpdate;

}


@end

私はそれをこのように呼びます

NSLog(@"Needs Update %@",[checkForUpdate checkForUpdateWithResponse] ? @"Yes":@"No");

これは私のログです

 Needs Update No
 Server Version 2.000000
 App Version 1.000000

チェックする前にNOを返す理由がわかりません。アプリがチェックするサーバーがファイアウォールの背後にあるため、非同期にする必要があります。そのため、ユーザーがファイアウォールの外側にいる場合、サーバーに到達できないときにアプリを続行する必要があります。私は正しい方向に向かっていますか、それとももっと良い方法がありますか?

4

2 に答える 2

3

dispatch_asyncは非ブロッキングであるため、更新情報が返される前にメソッドが返されます(ディスパッチを実行して続行します)。needsUpdateデフォルトでは、それが表示されNOます。これはログのタイミングで確認できます。サーバーとアプリのバージョンの前に「NeedsUpdateNo」が表示されます。

正しい結果を確実に得るには、何らかのコールバック(dispatch_asyncたとえば、デリゲートメソッドまたは秒)が必要です。そうでない場合は、ブロックする必要があります。を調べることをお勧めします。これにより、完了時に完了ハンドラーが実行され、更新を処理するために必要なコードをすべて使用できますNSURLConnectionsendAsynchronousRequest:queue:completionHandler:

于 2013-02-27T16:25:35.947 に答える
3

非同期で更新をチェックしていますが、メソッドの設計により即時の応答を期待しています。以下の例のようにメソッドを再設計して、操作が完了するたびにハンドラーに通知することができます。

注:エラーのチェックとテストは行われていません。ただし、この例から収集する教訓は、ある種のコールバックを使用することです。

UpdateCheckerクラス

typedef void (^onComplete)(BOOL requiresUpdate);

@interface UpdateChecker : NSObject
-(void)checkForUpdates:(onComplete)completionHandler;
@end

@implementation UpdateChecker
-(void)checkForUpdates:(onComplete)completionHandler
{
    NSString *urlStringVersion = [[NSString alloc] initWithFormat:@"http://URL/app_info?app=app"];
    NSURL *urlVersion = [NSURL URLWithString:urlStringVersion];
    dispatch_block_t executionBlock = 
    ^{
         /*
             Your update checking script here
             (Use the same logic you are currently using to retrieve the data using the url)
          */
         NSData* data = [NSData dataWithContentsOfURL:urlVersion];
         BOOL requiresUpdate = NO; 
         if (data)
         { 
             ...
             ...
             ...
             requiresUpdate = ...; //<-whatever your outcome
         }

         //Then when completed, notify the handler (this is our callback)
         //Note: I typically call the handler on the main thread, but is not required.  
         //Suit to taste.
         dispatch_async(dispatch_get_main_queue(),
         ^{
             if (completionHandler!=NULL)
                 completionHandler(requiresUpdate);
         });
    };
    dispatch_async(kBgQueue, executionBlock);
}
@end

これは、UpdateCheckerを使用してアプリ全体の更新を確認したときに表示されるものです。

UpdateChecker *checker = [UpdateChecker alloc] init];
[checker checkForUpdates:^(BOOL requiresUpdate)
{
     if (requiresUpdate)
     {
        //Do something if your app requires update
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
     }
     else         
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}];
于 2013-02-27T16:28:42.790 に答える