wifi網路打不開?!我要如何處理這個錯誤呢,讓使用者知道網路目前不通,而不是簡單的說wifi不通? 甚至是當機呢?! |
我是NSError錯誤, 我可以幫您表示現在發生了什麼錯誤, 只要將您的錯誤資訊提供給我保存就可以了, 如此您就可以後續依照保存在NSError中的錯誤資訊, 提示使用者現發生什麼事了。 |
1. 建立iPad
- 建立iPad類別
- 加入isAirPlaneModeOn屬性與setAirPlaneModeOn:方法,以提供開啟關閉飛航模式的功能
- 加入hasSignal方法,取得目前有訊號
iPad.h
#import <Foundation/Foundation.h>
@interface iPad : NSObject
//取得飛航模式狀態
@property (readonly) BOOL isAirPlaneModeOn;
//開啟與關閉飛航模式
-(void) setAirPlaneModeOn:(BOOL) yesno;
//手機是否有訊號
-(BOOL) hasSignal;
@end
iPad.m
#import "iPad.h"
@implementation iPad
//取得飛航模式狀態
@synthesize isAirPlaneModeOn = _isAirPlaneModeOn;
//開啟與關閉飛航模式
-(void) setAirPlaneModeOn:(BOOL) yesno
{
_isAirPlaneModeOn = yesno;
}
//手機是否有訊號
-(BOOL) hasSignal
{
//以arc4random_uniform()產生0或1,以表示是否有訊號,
//0表示沒有,
//1表示有
return (BOOL)arc4random_uniform(2);
}
@end
2. 為連結wifi的方法加上error參數
- 於iPad.h中宣告connectInternetWithWifi:(NSError**)errorPtr方法,其中的errorPtr參數即是一個NSError的指標的指標參數,用以指向error物件,以透過errorPtr參數將error物件代出給使用者
- 於iPad.m中,即可判斷是否有訊號,或是否因為飛航模式而無法連結wifi網路,若是的話則建立NSError物件,在透過errorPtr參數指向此error物件,以傳回給使用者,如下:
iPad.h
#import <Foundation/Foundation.h>
@interface iPad : NSObject
//略過一些程式
//加入NSError參數,
//目的在連結wifi網路時,
//若無法連絡,
//則傳回NSError物件,
//以透過NSError物件了解為何會無法連網。
//注意,在此的errorPtr參數是一個NSError型別的指標的指標,
//用意是我們將帶入一個指標的指標變數,
//以指向這個NSError物件。
-(void) connectInternetWithWifi:(NSError**) errorPtr;
@end
iPad.m
#import "iPad.h"
@implementation iPad
//略過一些程式
-(void) connectInternetWithWifi:(NSError**) errorPtr;
{
//飛航模式已開啟
if(_isAirPlaneModeOn == YES)
{
//建立NSRrror物件,
//其中有3個自訂的資訊可代入,
//Domain => 表示error的範圍,在此代入WifiOperation,
//表示是操作wifi時所產生的錯誤
//code => 表示error的代碼,在此以1表示飛航模式已開啟
//userInfo => 以NSDictionary表示其他資訊,
//在此代入一個message資訊,
//讓使用者了解發生了什麼錯誤
*errorPtr = [[NSError alloc]initWithDomain:@"WifiOperation"
code:1
userInfo:[NSDictionary dictionaryWithObjectsAndKeys: @"飛航模式已開啟", @"message", nil]];
return;
}
//手機沒訊號
if([self hasSignal] == 0)
{
//此code為2,表示手機沒訊號
//message資訊則代入"手機沒訊號"字樣
*errorPtr = [[NSError alloc]initWithDomain:@"WifiOperation"
code:2
userInfo:[NSDictionary dictionaryWithObjectsAndKeys: @"手機沒訊號", @"message", nil]];
return;
}
NSLog(@"wifi網路連線中...已連線!");
}
@end
3. 實際連結Wifi測試
- 此時,當iPad連線wifi網路時,則可能因為無訊息,或是飛航模式的開啟,導致無法連結wifi網路
- 但因為透過NSError的關係,此時若發生錯誤,則可查看發生了什麼錯誤,而後在回報給使用者,如此就會很清楚到底是何原因無法連上wifi了
#import "iPad.h"
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
iPad * pad1 = [[iPad alloc] init];
NSError * error;
//連線時,有可能因為沒訊號而產生error
[pad1 connectInternetWithWifi:&error];
if(error != nil)
NSLog(@"%@", [[error userInfo] objectForKey:@"message"]);
//刻意開啟飛航模式
//當然就一定連不上wifi,
//直接發生錯誤
[pad1 setAirPlaneModeOn:YES];
[pad1 connectInternetWithWifi:&error];
if(error != nil)
NSLog(@"%@", [[error userInfo] objectForKey:@"message"]);
}
return 0;
}
檔案連結:objective_c_nserror.zip
block與NSError:
- 在objective-C與iOS程式設計中,NSError時常會與block搭配使用,block讓使用者可自行定義後續的工作,同時block也接收NSError物件,以判斷是否有錯誤,以決定是否要繼續後續的工作
- 以連結wifi網路為例,透過block可讓使用者在連結wifi後做自已想作的事,當然若block中又接收NSError,則可透過NSError的判斷,決定是否要進行後續的作業,如下:
iPad.h
#import <Foundation/Foundation.h>
//定義傳入block型別,
//其中帶有NSError參數
typedef void (^doBlock_type)(NSError**);
@interface iPad : NSObject
//取得飛航模式狀態
@property (readonly) BOOL isAirPlaneModeOn;
//開啟與關閉飛航模式
-(void) setAirPlaneModeOn:(BOOL) yesno;
//手機是否有訊號
-(BOOL) hasSignal;
//定義connectInternetWithWifiThenDoBlock方法,
//其中代入doBlock_type型別的block
-(void) connectInternetWithWifiThenDoBlock: (doBlock_type)block_param;
@end
iPad.m
#import "iPad.h"
@implementation iPad
//取得飛航模式狀態
@synthesize isAirPlaneModeOn = _isAirPlaneModeOn;
//開啟與關閉飛航模式
-(void) setAirPlaneModeOn:(BOOL) yesno
{
_isAirPlaneModeOn = yesno;
}
//手機是否有訊號
-(BOOL) hasSignal
{
//以arc4random_uniform()產生0或1,以表示是否有訊號,
//0表示沒有,
//1表示有
return (BOOL)arc4random_uniform(2);
}
-(void) connectInternetWithWifiThenDoBlock: (doBlock_type)block_param;
{
NSError * errorPtr;
//飛航模式已開啟
if(_isAirPlaneModeOn == YES)
{
//建立NSRrror物件,
//其中有3個自訂的資訊可代入,
//Domain => 表示error的範圍,在此代入WifiOperation,
//表示是操作wifi時所產生的錯誤
//code => 表示error的代碼,在此以1表示飛航模式已開啟
//userInfo => 以NSDictionary表示其他資訊,
//在此代入一個message資訊,
//讓使用者了解發生了什麼錯誤
errorPtr = [[NSError alloc]initWithDomain:@"WifiOperation"
code:1
userInfo:[NSDictionary dictionaryWithObjectsAndKeys: @"飛航模式已開啟", @"message", nil]];
block_param(&errorPtr);
return;
}
//手機沒訊號
if([self hasSignal] == 0)
{
//此code為2,表示手機沒訊號
//message資訊則代入"手機沒訊號"字樣
errorPtr = [[NSError alloc]initWithDomain:@"WifiOperation"
code:2
userInfo:[NSDictionary dictionaryWithObjectsAndKeys: @"手機沒訊號", @"message", nil]];
block_param(&errorPtr);
return;
}
NSLog(@"wifi網路連線中...已連線!");
block_param(nil);
}
@end
main.m
#import "iPad.h"
#import >Foundation/Foundation.h<
int main(int argc, const char * argv[])
{
@autoreleasepool {
iPad * pad1 = [[iPad alloc] init];
//當然block也可以透過"^{}"直接建立block實體後代入,
//只要符合block的型別doBlock_type,
//所定義的回傳值與參數就ok了
[pad1 connectInternetWithWifiThenDoBlock:^(NSError ** errorPtr){
if(errorPtr != nil){
//NSLog(@"%@", [[errorPtr userInfo] objectForKey:@"message"]);
}
else
{
NSLog(@"上FB找朋友聊天!");
}
}];
}
return 0;
}
那Objective-C是否也有try/catch呢?:
- 當然,objective-c也有所謂的try/catch,當在整個objective-c與ios的設計上,皆習慣使用NSError來處理錯誤
- Apple建議try/catch是給程式設計人員使用的,而非使用您套件的使用者使用的
- 其try/catch語法如下:
@try
{
}
@catch
{
}
@finally
{
}
更多NSError的資訊: