2014年8月21日 星期四

Detect Internet status programmatically using Swift and Object-C language

【說明】

此份筆記將紀錄如何偵測網路的連接型態以及監聽網路是否有斷線。


【專案開發步驟】

建立專案:

使用Single View Application模板建立一個名為connectingAbility的專案,使用iPhone裝置。

設計使用者介面:

使用TabBarController包著兩個NavigationController,每個NavigationController各帶有一個View,在兩個View上面各加一個Button,並替每個ViewController設定File's owner,如下圖所示。
設計使用者介面

加入Reachability:

Reachability這個Class是由Apple提供的,定義一些method讓我們可以抓取到裝置網路的狀況,我們可以從Apple提供的Sample Code專案內取得這個Class,如下圖所示。
Reachability專案

設定Reachability Class:

修改Reachability.m檔,在dealloc的函式內加入[super dealloc],如下圖所示。
修改dealloc函式

告訴Compiler關閉Reachability.m的ARC,如下圖所示。
關閉ARC

加入所需要的Framework至專案內,如下圖所示。
加入Framework

import Reachability Class:

Swift:
需要建立一個與Object-C橋接的檔案,請參考這裡,在橋接檔案內import Reachability.h檔,之後的每個ViewController皆可使用Reachability這個Class,不需額外import,如下圖所示。
修改橋接檔案內容

Object-C:
在所需要用到Reachability Class的.m檔內新增#import "Reachability.h",如下圖所示。
import h檔

修改StatusViewController:

當按鈕按下後開始判斷所適用的網路是WiFi、WWAN或是沒連線,將以下程式碼加入到接收按鈕按下的func內,如下所示。

<Swift>
@IBAction func click(sender: UIButton) {
    let statusReach: Reachability = Reachability.reachabilityForInternetConnection()
    let networksStatus: NetworkStatus = statusReach.currentReachabilityStatus()
    var status: NSString!
    if networksStatus.value == 0 {
        status = "NoReachable"
    } else if networksStatus.value == 1 {
        status = "ReachableViaWiFi"
    } else {
        status = "ReachableViaWWAN"
    }
    navigationItem.prompt = status
    var timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "cancelPrompt", userInfo: nil, repeats: false)
}

func cancelPrompt() {
    navigationItem.prompt = nil
}

<Object-C>
- (IBAction)statusClick:(UIButton *)sender {
    Reachability *statusReach = [Reachability reachabilityForInternetConnection];
    NetworkStatus networkStatus = [statusReach currentReachabilityStatus];
    NSString *status;
    switch (networkStatus) {
        case NotReachable:
            status = @"NotReachable";
            break;
        
        case ReachableViaWWAN:
            status = @"ReachableViaWWAN";
            break;
            
        case ReachableViaWiFi:
            status = @"ReachableViaWiFi";
            break;
            
        default:
            break;
    }
    self.navigationItem.prompt = status;
    [self performSelector:@selector(cancelPrompt) withObject:nil afterDelay:10];
}

- (void)cancelPrompt {
    self.navigationItem.prompt = nil;
}
statusReach判斷現在是否連接上網路。networkStatus用來儲存目前連接網路的類型。得到連接網路的類型後去將status這個NSString設定文字。將status文字顯示在Navigation的Prompt內。延遲10後在去執行cancelPrompt這個method。

修改ChangeViewController:

將以下程式碼加入到viewDidLoad內,如下所示。

<Swift>
NSNotificationCenter.defaultCenter().addObserverForName(kReachabilityChangedNotification, object: nil, queue: NSOperationQueue.mainQueue()) { (NSNotification) -> Void in
    let networksStatus: NetworkStatus = self.internetReachability.currentReachabilityStatus()
    var status: NSString!
    if networksStatus.value == 0 {
        status = "Disconnection"
    } else if networksStatus.value == 1 {
        status = "Connection"
    } else {
        status = "Connection"
    }
    self.navigationItem.prompt = status
}

<Object-C>
[[NSNotificationCenter defaultCenteraddObserverForName:kReachabilityChangedNotification object:nil queue:[NSOperationQueue mainQueueusingBlock:^(NSNotification *note) {
    NetworkStatus networkStatus = [self.internetReachability currentReachabilityStatus];
    NSString *status;
    switch (networkStatus) {
        case NotReachable:
            status = @"Disconnection";
            break;
            
        case ReachableViaWWAN:
            status = @"Connection";
            break;
                
        case ReachableViaWiFi:
            status = @"Connection";
            break;
                
        default:
            break;
    }
    self.navigationItem.prompt = status;
}];
像NSNotificationCenter註冊一個監聽者。networkStatus取得目前網路的狀態。判斷是否可以連線。將狀態給NavigationItem的Prompt去顯示。

當按鈕按下後開始監聽網路連線狀態是否有改變,如下所示。

<Swift>
@IBAction func click(sender: UIButton) {
    self.internetReachability = Reachability.reachabilityForInternetConnection()
    self.internetReachability.startNotifier()
}

<Object-C>
- (IBAction)checkStatus:(UIButton *)sender {
    self.internetReachability = [Reachability reachabilityForInternetConnection];
    [self.internetReachability startNotifier];
}
當按鈕按下後internetReachability取得是否有連線。執行startNotifier,當連線的狀況有改變時會發送Notification給NSNotificationCenter,對應到的監聽者就會收到所發送的狀態。


【執行結果】

    

    

    


【專案範例】

沒有留言:

張貼留言