2011-01-23 9 views
10

का उपयोग कर इंटरनेट खो जाने/पहुंचने योग्य नहीं है, वर्तमान में मैं केवल सेब एक्सेसिबिलिटी.एम/एचएच द्वारा कक्षा का उपयोग कर रहा हूं और यह काम करता है, सिवाय इसके कि यह मुझे किसी के लिए सूचित करता है बदलें, जहां मैं केवल उपयोगकर्ता को सूचित करना चाहता हूं यदि नेटवर्क पहुंच योग्य नहीं है। वर्तमान में यदि मेरे पास इंटरनेट कनेक्शन है और फिर नेटवर्क खोला है तो यह मुझे बताता है। हालांकि जब आप नेटवर्क से कनेक्ट होते हैं तो यह मुझे भी बताता है, जिसे मैं नहीं चाहता। मैं चाहता हूं कि यह केवल मुझे बताए कि नुकसान होने पर कोई नेटवर्क नहीं है।आईओएस/आईफोन रीचैबिलिटी - रीचैबिलिटी.एम/एचएच

मेरा मानना ​​है कि यह कॉल के साथ कुछ है:

- (void)viewWillAppear:(BOOL)animated 
{ 
    // check for internet connection 
    [[NSNotificationCenter defaultCenter] 
      addObserver:self 
      selector:@selector(checkNetworkStatus:) 
       name:kReachabilityChangedNotification 
       object:nil]; 

    internetReachable = [[Reachability 
         reachabilityForInternetConnection] retain]; 
    [internetReachable startNotifier]; 

    // check if a pathway to a random host exists 
    hostReachable = [[Reachability reachabilityWithHostName: 
        @"www.google.ca"] retain]; 
    [hostReachable startNotifier]; 

    // now patiently wait for the notification 
} 

जब -[NSNotificationCenter addObserver:selector:name:object:] बुला, नाम किसी अन्य समारोह तो सचमुच एक नाम किया जा रहा है? यह मेरा पहला समय NSNotificationCenter का उपयोग कर रहा है, इसलिए मैं इस मामले में अच्छी तरह से नहीं जानता हूं।

संपादित करें:

यहाँ मेरी checkNetworkStatus समारोह है: (i हो रही समस्या है "NotReachable" कई बार नेटवर्क कनेक्शन के रूप में वापस आ रहा है और NSAlert बंद हो जाता है)

- (void) checkNetworkStatus:(NSNotification *)notice 
{ 
     // called after network status changes 
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus]; 
switch (internetStatus) 

{ 
    case NotReachable: 
    { 
     UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Network Failed" message:@"Please check your connection and try again." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil ]; 
     [alert show]; 
     NSLog(@"The internet is down."); 

     break; 

    } 
    case ReachableViaWiFi: 
    {    
     NSLog(@"The internet is working via WIFI."); 

     break; 

    } 
    case ReachableViaWWAN: 
    { 
     NSLog(@"The internet is working via WWAN."); 

     break; 

    } 
} 

NetworkStatus hostStatus = [hostReachable currentReachabilityStatus]; 
switch (hostStatus) 

{ 
    case NotReachable: 
    { 
     NSLog(@"A gateway to the host server is down."); 

     break; 

    } 
    case ReachableViaWiFi: 
    { 
     NSLog(@"A gateway to the host server is working via WIFI."); 

     break; 

    } 
    case ReachableViaWWAN: 
    { 
     NSLog(@"A gateway to the host server is working via WWAN."); 

     break; 

    } 
} 

}

+0

मजेदार बात: मैंने अभी देखा है कि यदि आईफोन एडहोक वाईफाई (कोई इंटरनेट कनेक्टिविटी नहीं) से जुड़ा हुआ है तो परिणाम वाईफाई के माध्यम से इंटरनेट कनेक्टिविटी के लिए अभी भी सकारात्मक है। –

+0

@rokjarc यही कारण है कि आप यह भी देखने के लिए जांच करते हैं कि मेजबान पहुंच योग्य है या नहीं। – Joe

+0

सत्य: असल में आमतौर पर आपको केवल इतना ही पता होना चाहिए। मुझे विश्वास है कि नामकरण गलत है: अलग-अलग AdHoc नेटवर्क में इंटरनेट (या WWW) पहुंच योग्य नहीं है ... लेकिन मैं यहाँ बाल बांट रहा हूं :) –

उत्तर

5

स्थिति बदल जाने पर पहुंच योग्यता अधिसूचना भेजी जाएगी, लेकिन उस अधिसूचना के साथ आप जो करते हैं वह पूरी तरह से आपके ऊपर है। यदि आप उपयोगकर्ता को यह नहीं बताना चाहते हैं कि नेटवर्क वापस आ गया है, तो आपको यह नहीं करना है।

NSNotificationCenter विधि में "नाम" पैरामीटर इंगित करता है कि आप किस अधिसूचना की सदस्यता ले रहे हैं। जब कोई ऑब्जेक्ट अधिसूचना पोस्ट करता है, तो यह किसी विशेष नाम से ऐसा करता है।

+0

कृपया मेरा संपादन देखें – Mausimo

0

मैं पूरी पहुंच योग्यता वर्ग लागू करता हूं, इसे आवश्यकतानुसार अपने कोड में जोड़ता हूं और पहुंच योग्यता के हिस्सों को हटा देता हूं या टिप्पणी करता हूं। बस एक-एक करके, उन चीज़ों को हटाएं जिन्हें आप अधिसूचित नहीं करना चाहते हैं। जाहिर है, आपको ओबीजे-सी, पहुंच योग्यता वर्ग, नोटिफिकेशन इत्यादि की अच्छी समझ की आवश्यकता है, लेकिन यह किया जा सकता है।

+0

कृपया मेरा संपादन देखें – Mausimo

+0

अलर्टव्यू प्रदर्शित किया जा रहा है कई बार क्योंकि चेकनेटवर्कस्टैटस उत्तराधिकार में कई बार बुलाया जा रहा है। आपको उस विधि के लिए अन्य कॉल ढूंढने और उन्हें हटाने की आवश्यकता है ताकि इसे केवल एक बार बुलाया जा सके। –

+0

मुझे समझ में नहीं आ रहा है, मैं केवल NSNotificationCenter पर चेकनेटवर्कस्टैटस डालता हूं ... – Mausimo

1

मैंने अभी तक पहुंच के साथ खेलना शुरू कर दिया और उम्मीद है कि मैंने जो खोजा है वह आपके लिए उपयोग में है।

रीकनेक्ट करते समय एकाधिक 'पहुंच योग्य नहीं' के संबंध में, क्या इसे this से जोड़ा जा सकता है? यहां पोस्टर ने रिमोट होस्ट के लिए 'पहुंच योग्य' की परिभाषा लाई। मैं अनुमान लगा रहा हूं कि पैकेज को दोबारा जोड़ने से सफलतापूर्वक गुजरने में सक्षम नहीं है?

एक और संभावना गम्यता Readme.txt में है

महत्वपूर्ण: गम्यता होस्ट नाम को हल करने से पहले यह कि मेजबान के गम्यता निर्धारित कर सकते हैं DNS का उपयोग करना चाहिए, और इस कुछ नेटवर्क कनेक्शन वाले समय लग सकता है। इस वजह से, एपीआई वापस लौटाएगा जब तक कि नाम समाधान पूरा नहीं हो जाता है। यह देरी कुछ नेटवर्क पर इंटरफ़ेस में दिखाई दे सकती है।

शायद इसे सीधे आईपी दें और देखें कि यह मदद करता है या नहीं?

0

एक चीज जो आप कर सकते हैं वह बदली गई अधिसूचना NSNotificationCenter removeObserver की सदस्यता रद्द कर रही है ... जबकि आप कॉलबैक में एक को संसाधित कर रहे हैं। लौटने से पहले पर्यवेक्षक वापस जोड़ें।

1

पहुंच योग्यता 2 के साथ।2, तो आप इस समस्या को हल करने से पहले

[internetReachable startNotifier]; 

[hostReach connectionRequired]; 

जोड़ सकते हैं।

runmad यहाँ इस समस्या को उत्तर दिया: https://stackoverflow.com/a/2157858/623260

2

तुम सिर्फ एक आईपी पता के साथ www.hostname.com की जगह है, यह केवल एक बार से अधिक बार के बजाय सूचित करेंगे।

0

हम

#import <sys/socket.h> 
      #import <netinet/in.h> 
      #import <netinet6/in6.h> 
      #import <arpa/inet.h> 
      #import <ifaddrs.h> 
      #import <netdb.h> 

      #import <CoreFoundation/CoreFoundation.h> 

      #import "Reachability.h" 

      #define kShouldPrintReachabilityFlags 1 

      static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment) 
      { 
      #if kShouldPrintReachabilityFlags 

       NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n", 
         (flags & kSCNetworkReachabilityFlagsIsWWAN)    ? 'W' : '-', 
         (flags & kSCNetworkReachabilityFlagsReachable)   ? 'R' : '-', 

         (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', 
         (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', 
         (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', 
         (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', 
         (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', 
         (flags & kSCNetworkReachabilityFlagsIsLocalAddress)  ? 'l' : '-', 
         (flags & kSCNetworkReachabilityFlagsIsDirect)    ? 'd' : '-', 
         comment 
         ); 
      #endif 
      } 


      @implementation Reachability 
      static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) 
      { 
       #pragma unused (target, flags) 
       NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback"); 
       NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback"); 

       //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively 
       // in case someon uses the Reachablity object in a different thread. 
       NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init]; 

       Reachability* noteObject = (Reachability*) info; 
       // Post a notification to notify the client that the network reachability changed. 
       [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject]; 

       [myPool release]; 
      } 

      - (BOOL) startNotifier 
      { 
       BOOL retVal = NO; 
       SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL}; 
       if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)) 
       { 
        if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) 
        { 
         retVal = YES; 
        } 
       } 
       return retVal; 
      } 

      - (void) stopNotifier 
      { 
       if(reachabilityRef!= NULL) 
       { 
        SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 
       } 
      } 

      - (void) dealloc 
      { 
       [self stopNotifier]; 
       if(reachabilityRef!= NULL) 
       { 
        CFRelease(reachabilityRef); 
       } 
       [super dealloc]; 
      } 

      + (Reachability*) reachabilityWithHostName: (NSString*) hostName; 
      { 
       Reachability* retVal = NULL; 
       SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]); 
       if(reachability!= NULL) 
       { 
        retVal= [[[self alloc] init] autorelease]; 
        if(retVal!= NULL) 
        { 
         retVal->reachabilityRef = reachability; 
         retVal->localWiFiRef = NO; 
        } 
       } 
       return retVal; 
      } 

      + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; 
      { 
       SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); 
       Reachability* retVal = NULL; 
       if(reachability!= NULL) 
       { 
        retVal= [[[self alloc] init] autorelease]; 
        if(retVal!= NULL) 
        { 
         retVal->reachabilityRef = reachability; 
         retVal->localWiFiRef = NO; 
        } 
       } 
       return retVal; 
      } 

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

      + (Reachability*) reachabilityForLocalWiFi; 
      { 
       struct sockaddr_in localWifiAddress; 
       bzero(&localWifiAddress, sizeof(localWifiAddress)); 
       localWifiAddress.sin_len = sizeof(localWifiAddress); 
       localWifiAddress.sin_family = AF_INET; 
       // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0 
       localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); 
       Reachability* retVal = [self reachabilityWithAddress: &localWifiAddress]; 
       if(retVal!= NULL) 
       { 
        retVal->localWiFiRef = YES; 
       } 
       return retVal; 
      } 

      #pragma mark Network Flag Handling 

      - (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags 
      { 
       PrintReachabilityFlags(flags, "localWiFiStatusForFlags"); 

       BOOL retVal = NotReachable; 
       if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect)) 
       { 
        retVal = ReachableViaWiFi; 
       } 
       return retVal; 
      } 

      - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags 
      { 
       PrintReachabilityFlags(flags, "networkStatusForFlags"); 
       if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) 
       { 
        // if target host is not reachable 
        return NotReachable; 
       } 

       BOOL retVal = NotReachable; 

       if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) 
       { 
        // if target host is reachable and no connection is required 
        // then we'll assume (for now) that your on Wi-Fi 
        retVal = ReachableViaWiFi; 
       } 


       if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0) || 
        (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) 
       { 
         // ... and the connection is on-demand (or on-traffic) if the 
         //  calling application is using the CFSocketStream or higher APIs 

         if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) 
         { 
          // ... and no [user] intervention is needed 
          retVal = ReachableViaWiFi; 
         } 
        } 

       if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) 
       { 
        // ... but WWAN connections are OK if the calling application 
        //  is using the CFNetwork (CFSocketStream?) APIs. 
        retVal = ReachableViaWWAN; 
       } 
       return retVal; 
      } 

      - (BOOL) connectionRequired; 
      { 
       NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef"); 
       SCNetworkReachabilityFlags flags; 
       if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 
       { 
        return (flags & kSCNetworkReachabilityFlagsConnectionRequired); 
       } 
       return NO; 
      } 

      - (NetworkStatus) currentReachabilityStatus 
      { 
       NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef"); 
       NetworkStatus retVal = NotReachable; 
       SCNetworkReachabilityFlags flags; 
       if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 
       { 
        if(localWiFiRef) 
        { 
         retVal = [self localWiFiStatusForFlags: flags]; 
        } 
        else 
        { 
         retVal = [self networkStatusForFlags: flags]; 
        } 
       } 
       return retVal; 
      } 
      @end 

इस कोड

ऐड वर्ग Reachability.h

#import <Foundation/Foundation.h> 
#import <SystemConfiguration/SystemConfiguration.h> 

typedef enum { 
NotReachable = 0, 
ReachableViaWiFi, 
ReachableViaWWAN 
} NetworkStatus; 
#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification" 

@interface Reachability: NSObject 
{ 
BOOL localWiFiRef; 
SCNetworkReachabilityRef reachabilityRef; 
} 

//reachabilityWithHostName- Use to check the reachability of a particular host name. 
+ (Reachability*) reachabilityWithHostName: (NSString*) hostName; 

//reachabilityWithAddress- Use to check the reachability of a particular IP address. 
+ (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; 

//reachabilityForInternetConnection- checks whether the default route is available. 
// Should be used by applications that do not connect to a particular host 
+ (Reachability*) reachabilityForInternetConnection; 

//reachabilityForLocalWiFi- checks whether a local wifi connection is available. 
+ (Reachability*) reachabilityForLocalWiFi; 

//Start listening for reachability notifications on the current run loop 
- (BOOL) startNotifier; 
- (void) stopNotifier; 

- (NetworkStatus) currentReachabilityStatus; 
//WWAN may be available, but not active until a connection has been established. 
//WiFi may require a connection for VPN on Demand. 
- (BOOL) connectionRequired; 
@end 

का उपयोग कर Reachability.m

rechability की जाँच करें और का उपयोग कर appdel कक्षा में प्रत्यक्ष बुला विधि के माध्यम से उपयोग कर सकते हैं

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil]; 



-(void) checkNetworkStatus:(NSNotification *)notice 
{ 

Reachability* internetReachable; 
    BOOL isInternetActive; 
// called after network status changes 
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus]; 
switch (internetStatus) 
{ 
    case NotReachable: 
    { 
     NSLog(@"The internet is down."); 
     isInternetActive = NO; 

     break; 
    } 
    case ReachableViaWiFi: 
    { 
     NSLog(@"The internet is working via WIFI."); 
     isInternetActive = YES; 

     break; 
    } 
    case ReachableViaWWAN: 
    { 
     NSLog(@"The internet is working via WWAN."); 
     isInternetActive = YES; 

     break; 
    } 
} 

NetworkStatus hostStatus = [hostReachable currentReachabilityStatus]; 
switch (hostStatus) 
{ 
    case NotReachable: 
    { 
     NSLog(@"A gateway to the host server is down."); 
     //   self.hostActive = NO; 

     break; 
    } 
    case ReachableViaWiFi: 
    { 
     NSLog(@"A gateway to the host server is working via WIFI."); 
     //   self.hostActive = YES; 

     break; 
    } 
    case ReachableViaWWAN: 
    { 
     NSLog(@"A gateway to the host server is working via WWAN."); 
     //   self.hostActive = YES; 

     break; 
    } 
} 
} 
+0

SCNetworkReachabilitySetCallback अब आईओएस 8 पर स्पष्ट रूप से अलग व्यवहार है जहां कॉलबैक कुछ समय बाद तक नहीं बनाया गया है और कनेक्टिविटी टूटने पर तुरंत नहीं। – cynistersix

संबंधित मुद्दे