問題:
最近在app發布之后, 有用戶反映有無法打開某些界面的問題. 明明網絡是通的,但就是無法從服務器取得數據,在開發環境無法復現。這時候很可能是用戶所在的網絡的DNS 服務器, 無法正確解析app的http api的域名.
我們假設api的域名為:api.hahaha.com
app的一個網絡請求, 可能會是這種格式:
對于域名api.hahaha.com, DNS的錯誤解析可能有兩種:
- 無法解析, 無法得到IP
- 錯誤解析, 返回錯誤IP
解決方法:
- 在發布app時, 內置一個默認IP, 例如
192.168.88.63
; - 在啟動時, 或者網絡連通性變化時, 解析域名;
+ (NSString *)getIPAddress:(NSString*) hostname{
Boolean result;
CFHostRef hostRef;
CFArrayRef addresses;
NSString *ipAddress = @"";
hostRef = CFHostCreateWithName(kCFAllocatorDefault, (__bridge CFStringRef)hostname);
if (hostRef) {
result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); // pass an error instead of NULL here to find out why it failed
if (result == TRUE) {
addresses = CFHostGetAddressing(hostRef, &result);
}
}
if (result == TRUE) {
CFIndex index = 0;
CFDataRef ref = (CFDataRef) CFArrayGetValueAtIndex(addresses, index);
struct sockaddr_in* remoteAddr;
char *ip_address;
remoteAddr = (struct sockaddr_in*) CFDataGetBytePtr(ref);
if (remoteAddr != NULL) {
ip_address = inet_ntoa(remoteAddr->sin_addr);
}
ipAddress = [NSString stringWithCString:ip_address encoding:NSUTF8StringEncoding];
}
return ipAddress;
}
- 檢查解析的結果
3.1 如果不能解析, 使用一個默認的IP地址代替域名;
之后的網絡請求為: https://192.168.88.63/login
3.2 如果解析成功,例如是192.168.87.62
,為了防止解析結果錯誤,可以采用一個檢測接口, 調用后,根據其響應(Http Response)內容, 檢查域名中的api接口是否正常;
https://api.hahaha.com/test
response: {state: "Im ok"}
3.2.1 如果api正常, 則使用域名進行請求. 并且將默認IP改為192.168.87.62
, 作為下次備用.
之后的網絡請求為: https://api.hahaha.com/login
3.2.2 如果域名不正常, 則使用默認IP
之后的網絡請求為: https://192.168.88.63/login
- 將域名或者IP設置為AFHTTPSessionManager的BaseURL進行正常的網絡請求