-1

アプリでAFNetworkingを使用しています。組み込みのクラスでインターネット接続を確認しています。これがこのコードです。

- (void) startInternetConnectivityMonitoring
{
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
    {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
            case AFNetworkReachabilityStatusReachableViaWWAN:
            case AFNetworkReachabilityStatusReachableViaWiFi:
                break;
            case AFNetworkReachabilityStatusNotReachable:
                break;
            default:
                break;
        }

        NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));

    }];

    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}

この関数で確認できます

- (BOOL) connected {
    return [AFNetworkReachabilityManager sharedManager].reachable;
}

また、アプリでRESideMenuを使用してサイド メニューを表示しています。これが私の- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法です。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self startInternetConnectivityMonitoring];

    RootViewController *rootView = [[RootViewController alloc] init];
    [rootView awakeFromNib];
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = rootView;
    [self.window makeKeyAndVisible];
    return YES;
}

FirstViewController を除く、他のすべてのビュー コントローラーではすべて正常に動作しています。FirstViewController では、ネットワーク リクエストを呼び出しています。その前に、インターネット接続を確認します。これが問題です。毎回No internet、FirstViewController が表示されます。ネットワーク要求を呼び出している間はAFNetworking、インターネットのステータスを更新しないためです。更新するのは数秒の摩擦かもしれませんが、それほど速くは更新されません. 私はこの問題を認識しているので、これを解決するためのパッチを適用したくありません。これを解決するためにさまざまなことを試しました。使用済み、

sleep(2);戻る前に YES からdidFinishLaunchingWithOptions...

dispatch_synq- アプリをフリーズ

dispatch_asynq- 機能しません

.. and many other hacky ways- まだ役に立ちません。

4

5 に答える 5

3

残念ながら、接続を判断するにはしばらく時間がかかるため、できるだけ早く行われることはおそらくないでしょう。ただし、インターネットに接続していると仮定するのではなく、到達可能性通知を受け取るように登録することもできます。AppDelegate didFinishLaunchingWithOptions:launchOptions で監視を開始します。

[[AFNetworkReachabilityManager sharedManager] startMonitoring];

FirstViewController の viewDidLoad または viewWillAppear で、通知を受け取るように登録します。

 [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(reachabilityChanged:)
                                              name:AFNetworkingReachabilityDidChangeNotification
                                            object:nil];

次に、FirstViewController にメソッドを追加して、通知を処理します。

- (void)reachabilityChanged:(NSNotification *)notification
{       
    if([[AFNetworkReachabilityManager sharedManager].isReachable)
    {
        // Do web service stuff here
    }
    else
    {
        // Do non webservice stuff
    }

ステータスが何であるかを知る必要がある場合は、通知の userInfo ディクショナリから取得できます。

- (void)reachabilityChanged:(NSNotification *)notification
{
    NSLog(@"Rechability Changed: %@", notification.userInfo);
    BOOL reachable;
    NSInteger status = [[notification.userInfo objectForKey:@"AFNetworkReachabilityNotificationStatusItem"] integerValue];
    switch(status)
    {
        case AFNetworkReachabilityStatusNotReachable:
            NSLog(@"No Internet Connection");
            reachable = NO;
            break;
        case AFNetworkReachabilityStatusReachableViaWiFi:
            NSLog(@"WIFI");
            reachable = YES;
            break;
        case AFNetworkReachabilityStatusReachableViaWWAN:
            NSLog(@"3G");
            reachable = YES;
            break;
        default:
            NSLog(@"Unkown network status");
            reachable = NO;
        break;
    }
    // do stuff with reachable
}

通知は、AFReachabilityManager がネットワーク ステータスを決定するとすぐに送信され、常に少なくとも 1 回送信されます。

ステータスを一度だけ取得する必要がある場合は、通知を処理するメソッドで通知センターから FirstViewController の登録を解除できます。

[[NSNotificationCenter defaultCenter] removeObserver:self];

または特定の通知の場合:

[[NSNotificationCenter defaultCenter] removeObserver:self name:AFNetworkingReachabilityDidChangeNotification object:nil];
于 2015-04-08T13:27:17.863 に答える
1

これに対する簡単なパッチを見つけました。もちろん、この問題の合理的な解決策は見つかりませんが、魅力的に機能するはずです。

  1. 取り入れましBOOLAppDelegate.h BOOL isCalledOnce;

  1. AppDelegate.m( )内に以下のような 2 つのメソッドを追加
- (void) setAppRequestCallOnce {
   isCalledOnce = YES;
}
 - (BOOL) checkAppRequestCalledOnce {
    return isCalledOnce;
 }

  1. 到達可能性チェックでは、このような条件を作りました。
- (BOOL) connected {
    if(![self checkAppRequestCalledOnce]) {
        [self setAppRequestCallOnce];
        return YES;
    }
    return [AFNetworkReachabilityManager sharedManager].reachable;
}

結論:

FirstViewController到達可能性を確認するときから、

if(![delegateObj connected]) {
    //show no internet message
}

checkAppRequestCalledOnceこれは最初に を返すメソッドを呼び出し、それがに設定されているisCalledOnce場合は を返します(ここでは、到達可能性の実際のステータスについてはわかりません)。これから、到達可能性を再度確認すると、上記の条件はチェックされず、実際の到達可能性ステータスが返されます。NOYESYES

使用している理由は、開始時にインターネットが利用できないAFNetworking場合でも、到達可能性の実際のステータスがなくても表示できますが、エラーが発生するためです。

もっとエレガントな方法を見つけたら、投稿またはコメントしてください。

于 2014-12-26T12:38:16.013 に答える
1

同様の問題がありました。AFNetworking が起動するまでに少し時間が必要なようです。 application:didFinishLaunchingWithOptions: でインターネット接続を確認する場合は、次を使用します。

Reachability *reach = [Reachability reachabilityForInternetConnection];

if (reach.currentReachabilityStatus != NotReachable) {
    //NSLog(@"internet available");
}

または AFNetworking にブロックを設定し、呼び出されるまで待ちます。

[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    if (status < ReachableViaWiFi) {
        // no connection
    } else {
        // connected
    }
}];

[[AFNetworkReachabilityManager sharedManager] startMonitoring];
于 2015-02-18T15:48:09.493 に答える
0

私も同じ種類の問題に直面しました。その後、Webサービスの呼び出しに0.3秒などの遅延を加えようとしたところ、問題が解決しました。

で web-service を呼び出す前に、多少の遅延を試みることができますFirstViewControllerAFNetworkingインターネットの状態を監視するのに時間がかかり、インターネットの状態を取得する前にコントローラーが読み込まれるためAFNetworkingです。だからあなたが得るたびにAFNetworkReachabilityStatusNotReachable

web-service を呼び出す前に少し時間を置いてFirstViewControllerください。問題が解決する場合があります。

于 2014-12-26T12:01:12.327 に答える
0

networkReachabilityStatusを確認すると、AFNetworking はまだステータスを決定していないことを通知しますAFNetworkReachabilityStatusUnknown。したがって、これを行うためのクリーンな方法は、reachableステータスがわかっている場合にのみステータスを使用することです。例えば:

- (void)networkReachableWithCompletion:(CompletionBlock)_completion
{
    if (!_completion) return; //no point continuing

    if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus != AFNetworkReachabilityStatusUnknown) {
        _completion([NSNumber numberWithBool:[AFNetworkReachabilityManager sharedManager].reachable]);
    } else {
        [self performSelector:@selector(networkReachableWithCompletion:) withObject:_completion afterDelay:0.3];
    }
}
于 2015-11-14T20:17:13.743 に答える