Ich versuche einen Weg zu finden, den Info-Bildschirm auf meinem App-Download aus dem Internet zu machen, WENN eine Internetverbindung verfügbar ist (so kann ich sie regelmäßig aktualisieren). Wenn kein Internet verfügbar ist, sollte das Standard oder das zuletzt heruntergeladene Internet verwendet werden. Ist das möglich?Dynamischer Info-Bildschirm
Antwort
Bitte beachten Sie, dass die oben von James Skitmore angebotene Methode eine schlechte Möglichkeit ist, die Konnektivität zu testen. Bitte tun nicht verwenden Sie es. Es wird unnötigerweise google.com laden, und es wird eine Zeitüberschreitung verursachen, sollte das Netzwerk nicht verfügbar sein, was Ihre App so aussieht, als wäre sie eingefroren.
So können Sie nach einer Netzwerkverbindung suchen.
In Ihrer App können Sie dies tun zu überprüfen, ob Netzwerk verfügbar ist:
if (![[UIDevice currentDevice] networkAvailable])
Sie können nun auch Verbindungen zu einem bestimmten Host, wie yourwebsite.com überprüfen, oder Sie können für die überprüfen Art der Verbindung, 3G vs Wifi, etc. Ich lasse Sie das herausfinden, indem Sie die Header-Dateien lesen.
Sie werden die folgenden Dateien in Ihre Anwendung müssen enthalten: (mit freundlicher Genehmigung von Erica Sadun)
UIDevice-Reachability.h
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License for anything not specifically marked as developed by a third party.
Zach Waugh and Apple's code excluded.
Use at your own risk
*/
#import <UIKit/UIKit.h>
#define SUPPORTS_UNDOCUMENTED_API 1
@interface UIDevice (Reachability)
- (NSString *) hostname;
- (NSString *) localWiFiIPAddress;
- (NSString *) localIPAddress;
- (NSString *) whatismyipdotcom;
- (BOOL) activeWLAN;
- (BOOL) addressFromString:(NSString *)IPAddress address:(struct sockaddr_in *)address; // via Apple
- (void) forceWWAN; // via Apple
- (void) shutdownWWAN; // via Apple
@end
// Methods which rely on undocumented API methods
#if SUPPORTS_UNDOCUMENTED_API
@interface UIDevice (UIDevice_Undocumented_Reachability)
- (BOOL) networkAvailable;
- (BOOL) activeWWAN;
@end
#endif // SUPPORTS_UNDOCUMENTED_API
UIDevice-Reachability.m
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License for anything not specifically marked as developed by a third party.
Apple's code excluded.
Use at your own risk
*/
// TTD: Add async version of whatsmyip -- thanks rpetrich
#include <unistd.h>
#include <sys/sysctl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <ifaddrs.h>
#import "UIDevice-Reachability.h"
#import "wwanconnect.h"
@implementation UIDevice (Reachability)
#pragma mark host and ip utils
- (NSString *) hostname
{
char baseHostName[255];
int success = gethostname(baseHostName, 255);
if (success != 0) return nil;
baseHostName[255] = '\0';
#if !TARGET_IPHONE_SIMULATOR
return [NSString stringWithFormat:@"%s.local", baseHostName];
#else
return [NSString stringWithFormat:@"%s", baseHostName];
#endif
}
// Direct from Apple. Thank you Apple
- (BOOL)addressFromString:(NSString *)IPAddress address:(struct sockaddr_in *)address
{
if (!IPAddress || ![IPAddress length]) {
return NO;
}
memset((char *) address, sizeof(struct sockaddr_in), 0);
address->sin_family = AF_INET;
address->sin_len = sizeof(struct sockaddr_in);
int conversionResult = inet_aton([IPAddress UTF8String], &address->sin_addr);
if (conversionResult == 0) {
NSAssert1(conversionResult != 1, @"Failed to convert the IP address string into a sockaddr_in: %@", IPAddress);
return NO;
}
return YES;
}
- (NSString *) getIPAddressForHost: (NSString *) theHost
{
struct hostent *host = gethostbyname([theHost UTF8String]);
if (host == NULL) {
herror("resolv");
return NULL;
}
struct in_addr **list = (struct in_addr **)host->h_addr_list;
NSString *addressString = [NSString stringWithCString:inet_ntoa(*list[0])];
return addressString;
}
#if ! defined(IFT_ETHER)
#define IFT_ETHER 0x6 // Ethernet CSMACD
#endif
// Matt Brown's get WiFi IP addy solution
// Author gave permission to use in Cookbook under cookbook license
// http://mattbsoftware.blogspot.com/2009/04/how-to-get-ip-address-of-iphone-os-v221.html
- (NSString *) localWiFiIPAddress
{
BOOL success;
struct ifaddrs * addrs;
const struct ifaddrs * cursor;
success = getifaddrs(&addrs) == 0;
if (success) {
cursor = addrs;
while (cursor != NULL) {
// the second test keeps from picking up the loopback address
if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
{
NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
if ([name isEqualToString:@"en0"]) { // found the WiFi adapter
return [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return nil;
}
// Return the local IP address
- (NSString *) localIPAddress
{
struct hostent *host = gethostbyname([[self hostname] UTF8String]);
if (host == NULL)
{
herror("resolv");
return nil;
}
else {
struct in_addr **list = (struct in_addr **)host->h_addr_list;
return [NSString stringWithCString:inet_ntoa(*list[0])];
}
return nil;
}
- (NSString *) whatismyipdotcom
{
NSError *error;
NSURL *ipURL = [NSURL URLWithString:@"http://www.whatismyip.com/automation/n09230945.asp"];
NSString *ip = [NSString stringWithContentsOfURL:ipURL encoding:1 error:&error];
if (!ip) return [error localizedDescription];
return ip;
}
- (BOOL) activeWLAN
{
return ([self localWiFiIPAddress] != nil);
}
#pragma mark Forcing WWAN connection
MyStreamInfoPtr myInfoPtr;
static void myClientCallback(void *refCon)
{
int *val = (int*)refCon;
printf("myClientCallback entered - value from refCon is %d\n", *val);
}
- (void) forceWWAN
{
int value = 0;
myInfoPtr = (MyStreamInfoPtr) StartWWAN(myClientCallback, &value);
if (myInfoPtr)
{
printf("Started WWAN\n");
}
else
{
printf("Failed to start WWAN\n");
}
}
- (void) shutdownWWAN
{
if (myInfoPtr) StopWWAN((MyInfoRef) myInfoPtr);
}
@end
#if SUPPORTS_UNDOCUMENTED_API
@implementation UIDevice (UIDevice_Undocumented_Reachability)
- (BOOL) networkAvailable
{
// Unavailable has only one address: 127.0.0.1
return !(([[[NSHost currentHost] addresses] count] == 1) && [[self localIPAddress] isEqualToString:@"127.0.0.1"]);
}
- (BOOL) activeWWAN
{
return ([self networkAvailable] && ![self localWiFiIPAddress]);
}
@end
#endif // SUPPORTS_UNDOCUMENTED_API
wwanconnect.h
// Direct from Apple. Thank you Apple
#if !defined(__WWAN_CONNECT__)
#define __WWAN_CONNECT__ 1
#include <CoreFoundation/CoreFoundation.h>
#include <assert.h>
#define kTestHost "www.whatismyip.com"
#define kTestPort 80
typedef void (*ConnectClientCallBack)(void *refCon);
struct MyStreamInfoStruct{
CFWriteStreamRef wStreamRef;
CFReadStreamRef rStreamRef;
ConnectClientCallBack clientCB;
void *refCon;
CFStreamError error;
Boolean errorOccurred;
Boolean isConnected;
Boolean isStreamInitd;
Boolean isClientSet;
};
typedef struct MyStreamInfoStruct MyStreamInfo;
typedef struct MyStreamInfoStruct *MyStreamInfoPtr;
typedef struct __MyInfoRef *MyInfoRef;
/*
* StartWWAN()
*
* Discussion:
* This function will initiate a Wireless Wide Area Network (WWAN)
* connection by using the CFSocketStream API to connect with a
* server system defined by kTestHost:kTestPort above.
* No communications are expected to happen over the CFSocketStream
* connection.
*
* clientCB:
* if the connection is opened, the callback routine, if not NULL
* will be called. function defintion - see ConnectClientCallBack above
*
* refCon:
* if a client callback, clientCB is defined, then the refCon
* parameter will be the argument to the client callback
*
* return:
* if the WWAN connection is successful, a MyInfoRef value is returned
* The MyInfoRef value must be passed to StopWWAN to stop the WWAN
* connection.
* A NULL result indicates that the connection was unsuccessful
*
*/
extern MyInfoRef StartWWAN(ConnectClientCallBack clientCB, void *refCon);
/*
* StopWWAN()
*
* Discussion:
* This function closes the CFSocketStream which was used to establish the
* WWAN connection. Once the WWAN connection has been started, BSD
* network functions can be used to communicate across the WWAN connection.
* As of the writing of this sample, there is no guarantee that the use of
* only BSD socket API's will maintain the WWAN connection.
*
* infoRef:
* pass in the MyInfoRef result from the StartWWAN function.
*
*/
extern void StopWWAN(MyInfoRef infoRef);
#endif // __WWAN_CONNECT__
wwanconnect.c
// Direct from Apple. Thank you Apple
#include "wwanconnect.h"
#include <CFNetwork/CFSocketStream.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <stdio.h>
static Boolean TestGetIFAddrs(void);
static void MyCFWriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType type, void *clientCallBackInfo);
static void CleanupAfterWAAN(MyStreamInfoPtr myInfoPtr);
static void CloseStreams(MyStreamInfoPtr myInfoPtr);
static Boolean TestGetIFAddrs(void)
{
int result;
struct ifaddrs *ifbase, *ifiterator;
int done = 0;
Boolean addrFound = FALSE;
char loopbackname[] = "lo0/0";
result = getifaddrs(&ifbase);
ifiterator = ifbase;
while (!done && (ifiterator != NULL))
{
if (ifiterator->ifa_addr->sa_family == AF_INET)
{
if (memcmp(ifiterator->ifa_name, loopbackname, 3))
{
struct sockaddr *saddr, *netmask, *daddr;
saddr = ifiterator->ifa_addr;
netmask = ifiterator->ifa_netmask;
daddr = ifiterator->ifa_dstaddr;
// we've found an entry for the IP address
struct sockaddr_in *iaddr;
char addrstr[64];
iaddr = (struct sockaddr_in *)saddr;
inet_ntop(saddr->sa_family, &iaddr->sin_addr, addrstr, sizeof(addrstr));
fprintf(stderr, "ipv4 interface name %s, source IP addr %s ", ifiterator->ifa_name, addrstr);
iaddr = (struct sockaddr_in *)netmask;
if (iaddr)
{
inet_ntop(saddr->sa_family, &iaddr->sin_addr, addrstr, sizeof(addrstr));
fprintf(stderr, "netmask IP addr %s ", addrstr);
}
iaddr = (struct sockaddr_in *)daddr;
if (iaddr)
{
inet_ntop(saddr->sa_family, &iaddr->sin_addr, addrstr, sizeof(addrstr));
fprintf(stderr, "dest/broadcast IP addr %s.\n\n", addrstr);
}
return TRUE;
}
}
else if (ifiterator->ifa_addr->sa_family == AF_INET6)
{
// we've found an entry for the IP address
struct sockaddr_in6 *iaddr6 = (struct sockaddr_in6 *)ifiterator->ifa_addr;
char addrstr[256];
inet_ntop(ifiterator->ifa_addr->sa_family, iaddr6, addrstr, sizeof(addrstr));
fprintf(stderr, "ipv6 interface name %s, source IP addr %s \n\n", ifiterator->ifa_name, addrstr);
}
ifiterator = ifiterator->ifa_next;
}
if (ifbase)
freeifaddrs(ifbase); /* done with the memory allocated by getifaddrs */
return addrFound;
}
static void MyCFWriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType type, void *clientCallBackInfo)
{
MyStreamInfoPtr myInfoPtr = (MyStreamInfoPtr) clientCallBackInfo;
printf("MyCFWriteStreamClientCallBack entered - event is %d\n", type);
switch (type)
{
case kCFStreamEventOpenCompleted:
myInfoPtr->isConnected = TRUE;
TestGetIFAddrs(); // call the test function to return the local ip address associated with this connection.
if (myInfoPtr->clientCB)
{
// call client callback routine
myInfoPtr->clientCB(myInfoPtr->refCon);
}
printf("write stream connected\n");
break;
case kCFStreamEventErrorOccurred:
myInfoPtr->errorOccurred = TRUE;
myInfoPtr->error = CFWriteStreamGetError(myInfoPtr->wStreamRef);
printf("write stream error %d .. giving up\n", myInfoPtr->error.error);
break;
default:
printf("event type %d occurred\n");
break;
}
// stop the run loop at this point
CFRunLoopStop(CFRunLoopGetCurrent());
}
extern MyInfoRef StartWWAN(ConnectClientCallBack clientCB, void *refCon)
{
char host[] = kTestHost;
int portNum = kTestPort;
CFDataRef addressData;
MyStreamInfoPtr myInfoPtr;
CFStreamClientContext ctxt = {0, NULL, NULL, NULL, NULL};
Boolean errorOccurred = FALSE;
myInfoPtr = malloc(sizeof(MyStreamInfo));
if (!myInfoPtr)
{
return NULL;
}
// init the allocated memory
memset(myInfoPtr, 0, sizeof(MyStreamInfo));
myInfoPtr->clientCB = clientCB;
myInfoPtr->refCon = refCon;
ctxt.info = myInfoPtr;
// Check for a dotted-quad address, if so skip any host lookups
in_addr_t addr = inet_addr(host);
if (addr != INADDR_NONE) {
// Create the streams from numberical host
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_len= sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = addr;
sin.sin_port = htons(portNum);
addressData = CFDataCreate(NULL, (UInt8 *)&sin, sizeof(sin));
CFSocketSignature sig = { AF_INET, SOCK_STREAM, IPPROTO_TCP, addressData };
// Create the streams.
CFStreamCreatePairWithPeerSocketSignature(kCFAllocatorDefault, &sig, &(myInfoPtr->rStreamRef), &(myInfoPtr->wStreamRef));
CFRelease(addressData);
} else {
// Create the streams from ascii host name
CFStringRef hostStr = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, host, kCFStringEncodingUTF8, kCFAllocatorNull);
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostStr, portNum, &(myInfoPtr->rStreamRef), &(myInfoPtr->wStreamRef));
}
myInfoPtr->isConnected = FALSE;
myInfoPtr->isStreamInitd = TRUE;
myInfoPtr->isClientSet = FALSE;
// Inform the streams to kill the socket when it is done with it.
// This effects the write stream too since the pair shares the
// one socket.
CFWriteStreamSetProperty(myInfoPtr->wStreamRef, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
// set up the client
if (!CFWriteStreamSetClient(myInfoPtr->wStreamRef, kCFStreamEventOpenCompleted | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
MyCFWriteStreamClientCallBack, &ctxt))
{
printf("CFWriteStreamSetClient failed\n");
errorOccurred = TRUE;
}
else
myInfoPtr->isClientSet = TRUE;
if (!errorOccurred)
{
// schedule the stream
CFWriteStreamScheduleWithRunLoop(myInfoPtr->wStreamRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
// Try to open the stream.
if (!CFWriteStreamOpen(myInfoPtr->wStreamRef))
{
printf("CFWriteStreamOpen failed\n");
errorOccurred = TRUE;
}
}
if (!errorOccurred)
{
// everything worked so far, so run the runloop - when the callback gets called, it will stop the run loop
printf("CFWriteStreamOpen returned with no error - calling CFRunLoopRun\n");
CFRunLoopRun();
if (myInfoPtr->errorOccurred)
errorOccurred = TRUE;
printf("after CFRunLoopRun - returning\n");
}
if (errorOccurred)
{
myInfoPtr->isConnected = FALSE;
CleanupAfterWAAN(myInfoPtr);
CloseStreams(myInfoPtr);
if (myInfoPtr->isStreamInitd)
{
CFRelease(myInfoPtr->rStreamRef);
CFRelease(myInfoPtr->wStreamRef);
myInfoPtr->isStreamInitd = FALSE;
}
free(myInfoPtr);
return NULL;
}
return (MyInfoRef)myInfoPtr;
}
static void CleanupAfterWAAN(MyStreamInfoPtr myInfoPtr)
{
assert(myInfoPtr != NULL);
if (myInfoPtr->isClientSet)
{
CFWriteStreamSetClient(myInfoPtr->wStreamRef, 0, NULL, NULL);
CFWriteStreamUnscheduleFromRunLoop(myInfoPtr->wStreamRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
myInfoPtr->isClientSet = FALSE;
}
}
static void CloseStreams(MyStreamInfoPtr myInfoPtr)
{
assert(myInfoPtr != NULL);
if (myInfoPtr->rStreamRef)
{
CFReadStreamClose(myInfoPtr->rStreamRef);
myInfoPtr->rStreamRef = NULL;
}
if (myInfoPtr->wStreamRef)
{
CFWriteStreamClose(myInfoPtr->wStreamRef);
myInfoPtr->wStreamRef = NULL;
}
}
extern void StopWWAN(MyInfoRef infoRef)
{
MyStreamInfoPtr myInfoPtr = (MyStreamInfoPtr)infoRef;
printf("stopWWAN entered\n");
assert(myInfoPtr != NULL);
myInfoPtr->isConnected = FALSE;
CleanupAfterWAAN(myInfoPtr);
CloseStreams(myInfoPtr);
free(myInfoPtr);
}
- 1. Dynamischer Variablenwert?
- 2. dynamischer jPlayer
- 3. Arrays dynamischer
- 4. Dynamischer Port
- 5. Dynamischer Slider
- 6. Dynamischer Inhalt/CMS
- 7. Umgang mit dynamischer URLs
- 8. Dynamischer Tabellenname in DAO.cfc?
- 9. C# dynamischer Operator
- 10. PHP dynamischer Klassenladen
- 11. C#, dynamischer Rückgabetyp
- 12. Dynamischer Systemimport mit Webpack?
- 13. dynamischer Rückgabetyp einer Funktion
- 14. Dynamischer Mesos-Cluster
- 15. Rmarkdown Dynamischer Inhalt
- 16. Münzwechselalgorithmus mit dynamischer Programmierung
- 17. Dynamischer Diagrammtitel aus Benutzerformular
- 18. MATLAB Filmfigur: dynamischer Datensatz
- 19. Python Logger dynamischer Dateiname
- 20. Dynamischer Versand und Bindung
- 21. dynamischer Teleport mit gml
- 22. Dynamischer LINQ Kontext
- 23. Dynamischer Funktionsaufruf PHP
- 24. Anruffunktion in dynamischer Linq
- 25. Dynamischer Pfad Helfer Schienen
- 26. AWS Lambda Dynamischer Endpunkt
- 27. VBA Dynamischer Name Bereich
- 28. Dynamischer Tabellenname mit Entitätsframework
- 29. Dynamischer Inhalt wird geladen
- 30. Action dynamischer Text