上面2个主要是说明证书申请和打包上传及审核流程,本文主要内容是解决app store上架的排名第三问题(据说是上架问题排行榜第三,也不知道是不是真的,姑且就当作是真的呗)。
如果项目中仅使用了http或https协议,那只需要把ip地址用域名就行了,另外尽量用nssession之类系统提供的api,毕竟iOS系统自己肯定是支持ipv6的(好像很多做iOS开发的都喜欢用第三方http库,个人觉得这么简单的东西,也没啥必要)。简单封装一下就可以了。
typedef void (^HttpHandler)(NSData* _Nullable data, NSURLResponse* _Nullable res, NSError* _Nullable e); + (void) httpAsAsynchronousRequestUrl:(NSString *)spec post:(NSString *)data httpHandler:(HttpHandler)handler { NSURL *url = [NSURL URLWithString:spec]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; if(data != nil){ request.HTTPMethod = @"POST"; request.HTTPBody = [data dataUsingEncoding:NSUTF8StringEncoding]; }else{ request.HTTPMethod = @"GET"; } [request setTimeoutInterval:15]; //application/json [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; //NSLog(@"%@",spec); NSURLSession *session = [NSURLSession sharedSession]; // 由于要先对request先行处理,我们通过request初始化task NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:handler]; [task resume]; } + (NSData*) httpAsSynchronousRequestUrl:(NSString *)spec post:(NSString* _Nullable)data { NSURL *url = [NSURL URLWithString:spec]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; if(data != nil){ request.HTTPMethod = @"POST"; request.HTTPBody = [data dataUsingEncoding:NSUTF8StringEncoding]; }else{ request.HTTPMethod = @"GET"; } //application/json [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; //NSLog(@"%@",spec); //NSURLSession *session = [NSURLSession sharedSession]; NSData* response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; return response; }
一个同步&异步2个方法
如果项目中不仅有http(https)协议,还有socket,也是需要做ipv6的支持的
下面是oc代码
//获取不同网络环境的IP地址 + (NSString *)getSockAddrIPString:(const struct sockaddr *)sa; //根据不同的网络环境设置端口 + (void)setPort:(uint16_t)port forSockAddr:(const struct sockaddr *)sa; @end @implementation IPv6Tester + (NSString *)getSockAddrIPString:(const struct sockaddr *)sa { NSString *result = @""; sa_family_t netType = sa->sa_family; if(netType == AF_INET) { char ipv4_str_buf[INET_ADDRSTRLEN] = {0}; struct sockaddr_in *v4sa = (struct sockaddr_in *)sa; inet_ntop(AF_INET,// &(v4sa->sin_addr),// ipv4_str_buf,// sizeof(ipv4_str_buf)); result = [[NSString alloc] initWithCString:ipv4_str_buf encoding:NSUTF8StringEncoding]; } else if(netType == AF_INET6) { char ipv6_str_buf[INET6_ADDRSTRLEN] = {0}; struct sockaddr_in6 *v6sa = (struct sockaddr_in6 *)sa; inet_ntop(AF_INET6,// &(v6sa->sin6_addr),// ipv6_str_buf,// sizeof(ipv6_str_buf)); result = [[NSString alloc] initWithCString:ipv6_str_buf encoding:NSUTF8StringEncoding]; } return result; } + (void)setPort:(uint16_t)port forSockAddr:(const struct sockaddr *)sa { sa_family_t netType = sa->sa_family; if(netType == AF_INET) { struct sockaddr_in *v4sa = (struct sockaddr_in *)sa; v4sa->sin_port = htons(port); } else if(netType == AF_INET6) { struct sockaddr_in6 *v6sa = (struct sockaddr_in6 *)sa; v6sa->sin6_port = htons(port); } } + (void)testMain { struct addrinfo res0; struct addrinfo *res1 = 0; struct addrinfo *res2 = 0; const char *cause = 0; //这里更换成你的服务器ip地址 const char *address = "xxx.xx.xx.xxx"; //这里是服务端口 NSUInteger port = 8084; memset(&res0, 0, sizeof(res0)); res0.ai_family = PF_UNSPEC; res0.ai_socktype = SOCK_STREAM; res0.ai_flags = AI_DEFAULT; int error = getaddrinfo(address, NULL, &res0, &res1); if (error) { //没有连接上 errx(1, "%s", gai_strerror(error)); } int s = -1; for (res2 = res1; res2; res2 = res2->ai_next) { s = socket(res2->ai_family, res2->ai_socktype, res2->ai_protocol); if (s < 0) { cause = "socket"; continue; } struct sockaddr *addr = (struct sockaddr *)res2->ai_addr; [TestIPV6 setPort:(uint16_t)port forSockAddr:addr]; NSString *ipString = [TestIPV6 getSockAddrIPString:addr]; NSLog(@"尝试连接地址 : %@", ipString); if (connect(s, res2->ai_addr, res2->ai_addrlen) < 0) { cause = "connect"; close(s); s = -1; continue; } break; } if(s >= 0) { UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:@"提示" message:@"连接成功" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"好的", nil]; [alertview show]; } else { //没有连接上 UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:@"提示" message:@"连接失败" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"好的", nil]; [alertview show]; err(1, "%s", cause); } freeaddrinfo(res1); } @end
如果纯C环境稍微改装下
#ifndef IPV6_h #define IPV6_h #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <err.h> #include <string.h> static std::string getSockAddrIPString(const struct sockaddr * sa) { std::string result; sa_family_t netType = sa->sa_family; if(netType == AF_INET) { char ipv4_str_buf[INET_ADDRSTRLEN] = {0}; struct sockaddr_in *v4sa = (struct sockaddr_in *)sa; inet_ntop(AF_INET,// &(v4sa->sin_addr),// ipv4_str_buf,// sizeof(ipv4_str_buf)); result = ipv4_str_buf; } else if(netType == AF_INET6) { char ipv6_str_buf[INET6_ADDRSTRLEN] = {0}; struct sockaddr_in6 *v6sa = (struct sockaddr_in6 *)sa; inet_ntop(AF_INET6,// &(v6sa->sin6_addr),// ipv6_str_buf,// sizeof(ipv6_str_buf)); result = ipv6_str_buf; } return result; } static void setPort(int port,const struct sockaddr * sa) { sa_family_t netType = sa->sa_family; if(netType == AF_INET) { struct sockaddr_in *v4sa = (struct sockaddr_in *)sa; v4sa->sin_port = htons(port); } else if(netType == AF_INET6) { struct sockaddr_in6 *v6sa = (struct sockaddr_in6 *)sa; v6sa->sin6_port = htons(port); } } static std::string convertServerAddr(const char* cpIpAddr,int nPort) { std::string server; if(strcmp(cpIpAddr,"0.0.0.0") == 0)return std::string("0.0.0.0");//过滤无效的ip地址 struct addrinfo res0; struct addrinfo *res1 = 0; struct addrinfo *res2 = 0; memset(&res0, 0, sizeof(res0)); res0.ai_family = PF_UNSPEC; res0.ai_socktype = SOCK_STREAM; res0.ai_flags = AI_DEFAULT; int error = getaddrinfo(cpIpAddr, NULL, &res0, &res1); if (error) { //没有连接上 errx(1, "%s", gai_strerror(error)); } int s = -1; for (res2 = res1; res2; res2 = res2->ai_next) { s = socket(res2->ai_family,res2->ai_socktype,res2->ai_protocol); if (s < 0)continue; struct sockaddr *addr = (struct sockaddr *)res2->ai_addr; setPort(nPort,addr); server = getSockAddrIPString(addr); printf("原地址:%s=>新地址:%s\n",cpIpAddr, server.c_str()); close(s); break; } freeaddrinfo(res1); return server; } #endif /* IPV6_h */
必须要引入的头文件,调用convertServerAddr方法就行了。最后就是搭建一个IPV6的无线环境,用真机测试。环境搭建教程:https://www.jianshu.com/p/632d995749e1 相对简单。
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (3)
-
std::string ip = convertServerAddr(pIpstr,iPort);域名转ipv6地址
if(strcmp(m_sBakAddr,pIpstr)!=0 || m_iBakPort!=iPort) { strcpy(m_sBakAddr,pIpstr); m_iBakPort =iPort; std::string ip = convertServerAddr(pIpstr,iPort); m_ServerAddr =tcp::endpoint(address::from_string(ip.c_str()),iPort); return 1; }
原地址:*.62.204.*=>新地址:2001:2:0:1baa::*:*
-
-
站点信息
- 文章2305
- 用户1336
- 访客11455432
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员