上面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::*:*
-
-
站点信息
- 文章2315
- 用户1336
- 访客11834022
每日一句
Each step leaves its mark, creating a landscape all its own.
一步一印,自成风景。
一步一印,自成风景。