Reachability在iOS7.0能正常工作么糠惫?Absolutely Not!

在WWDC2015上蘋果宣布iOS9將支持純IPv6的網(wǎng)絡(luò)服務(wù)靴患。2016年初開始所有提交到App Store的應(yīng)用必須支持IPv6。這早已不是新鮮事豁状,網(wǎng)上也出了大部分博文供我們參考怎么支持IPv6,關(guān)于Reachability捉偏,蘋果也推出了Version 5.0,用來支持IPv6,但細(xì)心的小伙伴可能會發(fā)現(xiàn)泻红,最新版的Reachability最低的系統(tǒng)要求是iOS 8.0夭禽。

Paste_Image.png

這個(gè)對于大部分開發(fā)者來說是沒有問題的,但是客戶非要支持iOS7.0怎么辦谊路?小弟我就遇到了這樣的客戶讹躯,趕緊在iOS7.0系統(tǒng)上測試最新的Reachability,希望不要有錯(cuò)缠劝,測試代碼如下:

Reachability *reachability = [Reachability reachabilityForInternetConnection];
NSLog(@"status:%ld",(long)[reachability currentReachabilityStatus]);

測試結(jié)果往往不如所愿蜀撑,如下圖,分別在IPv6剩彬、IPv4網(wǎng)絡(luò)環(huán)境下使用iOS9.0以及iOS7.0手機(jī)測試酷麦,iOS7.0系統(tǒng)的手機(jī)在IPv6網(wǎng)絡(luò)環(huán)境下是無法得到這確結(jié)果的。(IPv6網(wǎng)絡(luò)環(huán)境搭建請看這里

Paste_Image.png

故我開始了對Reachability的改造之路喉恋,目的是想讓它在iOS7上同樣支持IPv6沃饶。
改造方法認(rèn)為為:

+ (instancetype)reachabilityForInternetConnection
{
 struct sockaddr_in zeroAddress;
 bzero(&zeroAddress, sizeof(zeroAddress));
 zeroAddress.sin_len = sizeof(zeroAddress);
 zeroAddress.sin_family = AF_INET;
 return [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress];
}

修改的思路為:

  • 獲取設(shè)備IP地址
  • 通過IP地址判斷當(dāng)前設(shè)備所處的網(wǎng)絡(luò)環(huán)境
  • 如果是IPv6網(wǎng)絡(luò)環(huán)境,則使用struct sockaddr_in6來構(gòu)造zeroAddress轻黑。
+ (instancetype)reachabilityForInternetConnection
{
    // IPv4
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;
    
    // 獲取IP地址
    NSString *ipStr = [self getIPAddress];
    NSLog(@"ip address:%@",ipStr);
    if ([ipStr rangeOfString:@"."].location == NSNotFound) {
        // IPv6
        struct sockaddr_in6 zeroAddress;
        bzero(&zeroAddress, sizeof(zeroAddress));
        zeroAddress.sin6_len = sizeof(zeroAddress);
        zeroAddress.sin6_family = AF_INET6;
        return [self reachabilityWithAddress:(const struct sockaddr *)&zeroAddress];
    }
    
    return [self reachabilityWithAddress:(const struct sockaddr *)&zeroAddress];
}

+ (NSString *)getIPAddress {
    NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = getifaddrs(&interfaces);    // retrieve the current interfaces - returns 0 on success
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            // Check if interface is en0 which is the wifi connection on the iPhone
            if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"] || [[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"pdp_ip0"])
            {
                // IPV4
                if (temp_addr->ifa_addr->sa_family == AF_INET){
                    // Get NSString from C String
                    address = [self formatIPV4Address:((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr];
                }
                
                // IPV6
                else if (temp_addr->ifa_addr->sa_family == AF_INET6){
                    address = [self formatIPV6Address:((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr];
                    if (address && ![address isEqualToString:@""] && ![address.uppercaseString hasPrefix:@"FE80"]) break;
                }
            }
            
            temp_addr = temp_addr->ifa_next;
        }
    }
    // Free memory
    freeifaddrs(interfaces);
    return address;
}

//for IPV6
+ (NSString *)formatIPV6Address:(struct in6_addr)ipv6Addr{
    NSString *address = nil;
    
    char dstStr[INET6_ADDRSTRLEN];
    char srcStr[INET6_ADDRSTRLEN];
    memcpy(srcStr, &ipv6Addr, sizeof(struct in6_addr));
    if(inet_ntop(AF_INET6, srcStr, dstStr, INET6_ADDRSTRLEN) != NULL){
        address = [NSString stringWithUTF8String:dstStr];
    }
    return address;
}

//for IPV4
+ (NSString *)formatIPV4Address:(struct in_addr)ipv4Addr{
    NSString *address = nil;
    
    char dstStr[INET_ADDRSTRLEN];
    char srcStr[INET_ADDRSTRLEN];
    memcpy(srcStr, &ipv4Addr, sizeof(struct in_addr));
    if(inet_ntop(AF_INET, srcStr, dstStr, INET_ADDRSTRLEN) != NULL){
        address = [NSString stringWithUTF8String:dstStr];
    }
    return address;
}

修改好之后再次測試(iOS7系統(tǒng)糊肤,IPv6環(huán)境):

Paste_Image.png

大功告成。
總結(jié):如果你的項(xiàng)目也需要適配iOS7.0,那么這個(gè)博客可能有些許幫助氓鄙,有這個(gè)要求的客戶應(yīng)該少數(shù)馆揉。如代碼有問題,希望給予指點(diǎn)抖拦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末升酣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子态罪,更是在濱河造成了極大的恐慌噩茄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复颈,死亡現(xiàn)場離奇詭異绩聘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門凿菩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來机杜,“玉大人,你說我怎么就攤上這事衅谷〗忿郑” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵会喝,是天一觀的道長。 經(jīng)常有香客問我玩郊,道長肢执,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任译红,我火速辦了婚禮预茄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侦厚。我一直安慰自己耻陕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布刨沦。 她就那樣靜靜地躺著诗宣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪想诅。 梳的紋絲不亂的頭發(fā)上召庞,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音来破,去河邊找鬼篮灼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扎狱,可吹牛的內(nèi)容都是我干的睬捶。 我是一名探鬼主播孕似,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娘荡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起驶沼,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤它改,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后商乎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體央拖,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鲜戒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片专控。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖遏餐,靈堂內(nèi)的尸體忽然破棺而出伦腐,到底是詐尸還是另有隱情,我是刑警寧澤失都,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布柏蘑,位于F島的核電站,受9級特大地震影響粹庞,放射性物質(zhì)發(fā)生泄漏咳焚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一庞溜、第九天 我趴在偏房一處隱蔽的房頂上張望革半。 院中可真熱鬧,春花似錦流码、人聲如沸又官。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽六敬。三九已至,卻和暖如春驾荣,著一層夾襖步出監(jiān)牢的瞬間觉阅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工秘车, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留典勇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓叮趴,卻偏偏與公主長得像割笙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子眯亦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 研究IPv6 socket編程原因: Supporting IPv6 in iOS 9 WWDC2015蘋果宣布在...
    li大鵬閱讀 7,326評論 7 15
  • 一伤溉、IPV6-Only支持是啥? 首先IPV6妻率,是對IPV4地址空間的擴(kuò)充乱顾。目前當(dāng)我們用iOS設(shè)備連接上Wifi、...
    一字碼閱讀 860評論 0 0
  • 生活平平淡淡宫静,少有浪花和色彩走净。反倒是夢券时,因?yàn)榻M合的奇異,有了新奇的效果伏伯。醒來總是讓人難以忘記橘洞。既然老是回味...
    梅影映雪閱讀 175評論 0 3
  • iOS常用的數(shù)據(jù)持久化方案主要有四種:NSUserDefault、File说搅、Keychain炸枣、FMDB。 NSUs...
    簡潔的想法閱讀 466評論 0 0
  • 5月23日,我這天也和往常一樣早起上班候引,每天習(xí)慣性地看看公司的公眾號侯养,前一天已經(jīng)有幕天捐書,為山區(qū)學(xué)生捐了六...
    梨樹花開閱讀 381評論 0 0