iOS - BSDSocket 的使用
1、BSDSocket
一套 unix 系统下的 socket API(纯 C)。
iOS 系统基于 unix,所以支持底层的 BSD Socket,在 Xcode 中可以直接使用。
2、基本使用
2.1 Client 客户端
TCP 客户端
包含头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
创建 Socket
// client Socket
@property (nonatomic, assign) int clientSocket; self.clientSocket = socket(AF_INET, SOCK_STREAM, 0); if (self.clientSocket > 0) {
NSLog(@"Socket 创建成功 %d", self.clientSocket);
} else {
NSLog(@"Socket 创建失败");
}
连接到服务器
// 创建服务器地址结构体
struct sockaddr_in serverAddress;
bzero(&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET; // 协议族
serverAddress.sin_port = htons(12345); // 端口 端口数据高位在前低位在后 12345 => 3039 => 3930
serverAddress.sin_addr.s_addr = inet_addr("192.168.88.100"); // inet_addr 函数可以把 ip 地址转换成一个整数 int isConnected = connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); if (isConnected) {
NSLog(@"连接失败 %d", isConnected);
} else {
NSLog(@"连接成功");
}
发送数据
NSString *message = @"你好"; ssize_t sendLen = send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0); if (sendLen > 0) {
NSLog(@"发送成功,发送 %ld 个字节数据", sendLen);
} else {
NSLog(@"发送失败 %zd", sendLen);
}
接收数据
// 接收字符串的数组,typedef unsigned char uint8_t;
uint8_t buffer[1024]; ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); if (recvLen > 0) { // 按照服务器返回的长度,从 buffer 中,读取二进制数据,建立 NSData 对象
NSData *data = [NSData dataWithBytes:buffer length:recvLen];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"接收成功,接收到 %ld 个字节数据\n 接收到:%@", recvLen, str);
} else {
NSLog(@"接收失败 %zd", recvLen);
}
关闭连接
// 数据传递完毕之后,关闭连接
int isCloseed = close(self.clientSocket); NSLog(@"%d", isCloseed);
2.2 Server 服务端
TCP 服务端
包含头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
创建 Socket
// server Socket
@property (nonatomic, assign) int serverSocket; // client Socket
@property (nonatomic, assign) int clientSocket; self.serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (self.serverSocket > 0) {
NSLog(@"Socket 创建成功 %d", self.serverSocket);
} else {
NSLog(@"Socket 创建失败");
}
开始监听
// 创建服务器地址结构体
struct sockaddr_in serverAddress;
bzero(&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(12345);
serverAddress.sin_addr.s_addr = inet_addr("192.168.88.100"); int isBind = bind(self.serverSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); if (isBind) {
NSLog(@"绑定失败 %d", isBind);
return;
} else {
NSLog(@"绑定成功");
} int isListen = listen(self.serverSocket, 10); if (isListen) {
NSLog(@"监听失败 %d", isListen);
return;
} else {
NSLog(@"监听成功");
} // clientSocket
struct sockaddr_in clientAddress;
bzero(&clientAddress, sizeof(clientAddress));
socklen_t len = sizeof(clientAddress); self.clientSocket = accept(self.serverSocket, (struct sockaddr *)&clientAddress, &len); if (self.clientSocket) {
NSLog(@"接收成功 %d,client IP:%zd", self.clientSocket, clientAddress);
} else {
NSLog(@"接收失败");
}
发送数据
NSString *message = @"你好"; // 使用 clientSocket
ssize_t sendLen = send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0); if (sendLen > 0) {
NSLog(@"发送成功,发送 %ld 个字节数据", sendLen);
} else {
NSLog(@"发送失败 %zd", sendLen);
}
接收数据
// 接收字符串的数组,typedef unsigned char uint8_t;
uint8_t buffer[1024]; // 使用 clientSocket
ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); if (recvLen > 0) { // 按照服务器返回的长度,从 buffer 中,读取二进制数据,建立 NSData 对象
NSData *data = [NSData dataWithBytes:buffer length:recvLen];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"接收成功,接收到 %ld 个字节数据\n 接收到:%@", recvLen, str);
} else {
NSLog(@"接收失败 %zd", recvLen);
}
关闭连接
// 数据传递完毕之后,关闭连接
int isCloseed = close(self.serverSocket); NSLog(@"%d", isCloseed);
3、网络访问
1、请求:
1)请求行
GET / HTTP/1.1
方法 GET
路径 /
协议 HTTP 1.1
2)请求头
- Host: localhost 主机
- User-Agent: 告诉服务器客户端的类型
- Accept: 告诉服务器客户端支持的格式
- Accept-Language: 告诉服务器客户端的语言
- Accept-Encoding: 告诉服务器客户端支持的压缩格式
2、响应:
1)状态行
HTTP/1.1 200 OK
- 协议 HTTP 1.1
- 状态码:
- 200 成功
- 404 页面没找到
- 301 内容没变化,用在缓存
2)响应头(主要在开发下载应用的时候使用的)
- Date: Tue, 24 Mar 2015 01:52:25 GMT 访问日期
- Server: Apache/2.4.9 (Unix) 访问服务器的类型
- Content-Location: index.html.en 访问的文件名
- Content-Length: 45 访问文件的大小
- Content-Type: text/html 访问文件的类型
3)数据实体
<html><body><h1>It works!</h1></body></html>
访问服务器最需的,相当于 NSURLConnection 异步方法回调中的 data。
TCP 客户端
// 包含头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <ifaddrs.h> @property (nonatomic, assign) int clientSocket; - (void)socketHttpRequest { // 连接到服务器,80 端口 apache 中就是 http 的协议
if (![self connection:@"127.0.0.1" port:80]) {
return;
} // 创建请求
NSString *requestStr = @"GET / HTTP/1.1\n"
"Host: localhost\n"
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"
"Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3\n" // \n 拼接换行,内容由 firefox 浏览器的网络控制面板的原始请求头信息中复制
"Accept-Encoding: gzip, deflate\n" // 删除最后三行,最后一行加两个 \n\n
"Connection: keep-alive\n\n"; // 发送接收请求,发送给 web 服务器的请求需要遵守 http 协议
NSString *recvStr = [self sendAndRecv:requestStr]; NSLog(@"%@", recvStr);
} /// 创建连接
- (BOOL)connection:(NSString *)hostText port:(int)port { // 创建 Socket self.clientSocket = socket(AF_INET, SOCK_STREAM, 0); // 连接到服务器 struct sockaddr_in serverAddress;
bzero(&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
serverAddress.sin_addr.s_addr = inet_addr(hostText.UTF8String); int isConnected = connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); return (isConnected == 0);
} /// 发送和接收字符串
- (NSString *)sendAndRecv:(NSString *)message { // 发送数据 send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0); // 接收数据 uint8_t buffer[1024]; ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); NSData *data = [NSData dataWithBytes:buffer length:recvLen];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return str;
}
4、客户端使用
TCP 客户端 & UDP
// 包含头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <ifaddrs.h> typedef NS_ENUM (NSInteger,ServerType) {
ServerTypeTCP,
ServerTypeUDP
}; @property (weak, nonatomic) IBOutlet UITextField *desIPTF;
@property (weak, nonatomic) IBOutlet UITextField *desPortTF; @property (weak, nonatomic) IBOutlet UITextField *locIPTF;
@property (weak, nonatomic) IBOutlet UITextField *locPortTF; @property (weak, nonatomic) IBOutlet UITextView *recvTextView;
@property (weak, nonatomic) IBOutlet UITextField *sendTF; @property (nonatomic, assign) int clientSockfd;
@property (nonatomic, assign) int udpSockfd; @property (nonatomic, assign) ServerType serType; - (void)viewDidLoad {
[super viewDidLoad]; NSString *ip_addr = [self getIPAddress];
_locIPTF.text = ip_addr;
} #pragma mark - 创建 TCP 连接 - (IBAction)connectTCPServer:(id)sender { [NSThread detachNewThreadSelector:@selector(connectTCPSer) toTarget:self withObject:nil];
} - (void)connectTCPSer { self.serType = ServerTypeTCP; BOOL success;
int err; // 创建 socket
self.clientSockfd = socket(AF_INET, SOCK_STREAM, 0);
success = (self.clientSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
[self showMessage:logStr]; // 服务器地址
struct sockaddr_in ser_addr;
memset(&ser_addr, 0, sizeof(ser_addr));
ser_addr.sin_len = sizeof(ser_addr);
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(_desPortTF.text.intValue);
ser_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); // 连接
err = connect(self.clientSockfd, (struct sockaddr *)&ser_addr, sizeof(ser_addr));
success = (err == 0);
} if (success == NO) { logStr = @"socket 连接失败...\n";
[self showMessage:logStr]; return; } else { logStr = [NSString stringWithFormat:@"socket 连接 %@ 成功...\n", _desIPTF.text];
[self showMessage:logStr]; char buf[1024];
do {
// 接收数据
ssize_t recvLen = recv(self.clientSockfd, buf, sizeof(buf), 0); if (recvLen > 0) {
logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
[self showMessage:logStr];
} } while (strcmp(buf, "exit") != 0);
}
} #pragma mark - 创建 UDP 连接 - (IBAction)connectUDP:(id)sender { [NSThread detachNewThreadSelector:@selector(connectUDP) toTarget:self withObject:nil];
} - (void)connectUDP { self.serType = ServerTypeUDP; BOOL success;
int err; // 创建 Socket
self.udpSockfd = socket(AF_INET, SOCK_DGRAM, 0);
success = (self.udpSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
[self showMessage:logStr]; // 本地地址
struct sockaddr_in loc_addr;
bzero(&loc_addr, sizeof(loc_addr));
loc_addr.sin_port = htons(_locPortTF.text.intValue);
loc_addr.sin_addr.s_addr = inet_addr(_locIPTF.text.UTF8String); // 绑定
err = bind(self.udpSockfd, (const struct sockaddr *)&loc_addr, sizeof(loc_addr));
success = (err == 0);
} if (success == NO) { logStr = @"socket 绑定失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"socket 绑定成功...\n";
[self showMessage:logStr]; // 目标地址
struct sockaddr_in des_addr;
bzero(&des_addr, sizeof(des_addr));
des_addr.sin_family = AF_INET;
des_addr.sin_port = htons(_desPortTF.text.intValue);
des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); char buf[256];
bzero(buf, sizeof(buf)); while(1) { // 接收数据
socklen_t des_addr_len = sizeof(des_addr);
ssize_t recvLen = recvfrom(self.udpSockfd, buf, sizeof(buf), 0, (struct sockaddr*)&des_addr, &des_addr_len); if (recvLen > 0) {
logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
[self showMessage:logStr];
}
}
}
} #pragma mark - 发送数据 - (IBAction)btnClick:(id)sender { if (_sendTF.text.length == 0) {
return;
} else { ssize_t sendLen; if (self.serType == ServerTypeTCP) { // 发送数据
sendLen = send(self.clientSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0); } else if (self.serType == ServerTypeUDP) { // 目标地址
struct sockaddr_in des_addr;
bzero(&des_addr, sizeof(des_addr));
des_addr.sin_family = AF_INET;
des_addr.sin_port = htons(_desPortTF.text.intValue);
des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); // 发送数据
sendLen = sendto(self.udpSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0,
(struct sockaddr *)&des_addr, sizeof(des_addr));
} if (sendLen > 0) {
NSString *logStr = [NSString stringWithFormat:@"send:%@\n", _sendTF.text];
[self showMessage:logStr];
}
}
} #pragma mark - 获取本地 IP 地址 - (NSString *)getIPAddress { NSString *address = @"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0; // retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces
temp_addr = interfaces; while (temp_addr != NULL) { if (temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
} // Free memory
freeifaddrs(interfaces);
return address;
} // 显示信息
- (void)showMessage:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ _recvTextView.text = [_recvTextView.text stringByAppendingString:msg];
});
}
5、服务端使用
TCP 服务端 & UDP
// 包含头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <ifaddrs.h> typedef NS_ENUM (NSInteger,ServerType) {
ServerTypeTCP,
ServerTypeUDP
}; @property (weak, nonatomic) IBOutlet UITextField *desIPTF;
@property (weak, nonatomic) IBOutlet UITextField *desPortTF; @property (weak, nonatomic) IBOutlet UITextField *locIPTF;
@property (weak, nonatomic) IBOutlet UITextField *locPortTF; @property (weak, nonatomic) IBOutlet UITextView *recvTextView;
@property (weak, nonatomic) IBOutlet UITextField *sendTF; @property (nonatomic, assign) int serverSockfd;
@property (nonatomic, assign) int clientSockfd; @property (nonatomic, assign) int udpSockfd; @property (nonatomic, assign) ServerType serType; - (void)viewDidLoad {
[super viewDidLoad]; NSString *ip_addr = [self getIPAddress];
_locIPTF.text = ip_addr;
} #pragma mark - 创建 TCP 监听 - (IBAction)createdTCPServer:(id)sender { _desIPTF.enabled = NO;
_desPortTF.enabled = NO;
_locPortTF.enabled = NO; [NSThread detachNewThreadSelector:@selector(createdTCPSer) toTarget:self withObject:nil];
} - (void)createdTCPSer { self.serType = ServerTypeTCP; BOOL success;
int err; // 创建 socket
self.serverSockfd = socket(AF_INET, SOCK_STREAM, 0);
success = (self.serverSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
[self showMessage:logStr]; // 本地地址
struct sockaddr_in loc_addr;
memset(&loc_addr, 0, sizeof(loc_addr));
loc_addr.sin_family = AF_INET;
loc_addr.sin_port = htons(_locPortTF.text.intValue);
loc_addr.sin_addr.s_addr = inet_addr(_locIPTF.text.UTF8String); // 绑定
err = bind(self.serverSockfd, (const struct sockaddr *)&loc_addr, sizeof(loc_addr));
success = (err == 0);
} if (success == NO) { logStr = @"socket 绑定失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"socket 绑定成功...\n";
[self showMessage:logStr]; // 监听
err = listen(self.serverSockfd, 5); // 5:最大连接个数
success = (err == 0);
} if (success == NO) { logStr = @"socket 监听失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"socket 监听成功...\n";
[self showMessage:logStr]; while (true) { // 循环 // 连接的客户端的地址
struct sockaddr_in cli_addr;
socklen_t cli_addr_Len = sizeof(cli_addr); // 接受客户端的请求,并建立连接
self.clientSockfd = accept(self.serverSockfd, (struct sockaddr *)&cli_addr, &cli_addr_Len);
success = (self.clientSockfd != -1); if (success) { char *ip_addr = inet_ntoa(cli_addr.sin_addr);
int ip_port = ntohs(cli_addr.sin_port);
dispatch_async(dispatch_get_main_queue(), ^{
_desIPTF.text = [NSString stringWithFormat:@"%s", ip_addr];
_desPortTF.text = [NSString stringWithFormat:@"%d", ip_port];
}); logStr = [NSString stringWithFormat:@"已连接:%s,port:%d\n", ip_addr, ip_port];
[self showMessage:logStr]; char buf[1024];
do {
// 返回读取的字节数
ssize_t recvLen = recv(self.clientSockfd, buf, sizeof(buf), 0); if (recvLen > 0) {
logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
[self showMessage:logStr];
} } while (strcmp(buf, "exit") != 0);
}
}
}
} #pragma mark - 创建 UDP 连接 - (IBAction)connectUDP:(id)sender { [NSThread detachNewThreadSelector:@selector(connectUDP) toTarget:self withObject:nil];
} - (void)connectUDP { self.serType = ServerTypeUDP; BOOL success;
int err; // 创建 Socket
self.udpSockfd = socket(AF_INET, SOCK_DGRAM, 0);
success = (self.udpSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
[self showMessage:logStr]; // 本地地址
struct sockaddr_in loc_addr;
bzero(&loc_addr, sizeof(loc_addr));
loc_addr.sin_port = htons(_locPortTF.text.intValue);
loc_addr.sin_addr.s_addr = inet_addr(_locIPTF.text.UTF8String); // 绑定
err = bind(self.udpSockfd, (const struct sockaddr *)&loc_addr, sizeof(loc_addr));
success = (err == 0);
} if (success == NO) { logStr = @"socket 绑定失败...\n";
[self showMessage:logStr]; return; } else { logStr = @"socket 绑定成功...\n";
[self showMessage:logStr]; // 目标地址
struct sockaddr_in des_addr;
bzero(&des_addr, sizeof(des_addr));
des_addr.sin_family = AF_INET;
des_addr.sin_port = htons(_desPortTF.text.intValue);
des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); char buf[256];
bzero(buf, sizeof(buf)); while(1) { // 接收数据
socklen_t des_addr_len = sizeof(des_addr);
ssize_t recvLen = recvfrom(self.udpSockfd, buf, sizeof(buf), 0, (struct sockaddr*)&des_addr, &des_addr_len); if (recvLen > 0) {
logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
[self showMessage:logStr];
}
}
}
} #pragma mark - 发送数据 - (IBAction)btnClick:(id)sender { if (_sendTF.text.length == 0) {
return;
} else { ssize_t sendLen; if (self.serType == ServerTypeTCP) { // 发送数据
sendLen = send(self.clientSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0); } else if (self.serType == ServerTypeUDP) { // 目标地址
struct sockaddr_in des_addr;
bzero(&des_addr, sizeof(des_addr));
des_addr.sin_family = AF_INET;
des_addr.sin_port = htons(_desPortTF.text.intValue);
des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); // 发送数据
sendLen = sendto(self.udpSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0,
(struct sockaddr *)&des_addr, sizeof(des_addr));
} if (sendLen > 0) {
NSString *logStr = [NSString stringWithFormat:@"send:%@\n", _sendTF.text];
[self showMessage:logStr];
}
}
} #pragma mark - 获取本地 IP 地址 - (NSString *)getIPAddress { NSString *address = @"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0; // retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces
temp_addr = interfaces; while (temp_addr != NULL) { if (temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
} // Free memory
freeifaddrs(interfaces);
return address;
} // 显示信息
- (void)showMessage:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ _recvTextView.text = [_recvTextView.text stringByAppendingString:msg];
});
}
iOS - BSDSocket 的使用的更多相关文章
- 聊聊iOS中网络编程长连接的那些事
1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...
- iOS即时通讯之CocoaAsyncSocket源码解析一
申明:本文内容属于转载整理,原文连接 前言: CocoaAsyncSocket是谷歌的开发者,基于BSD-Socket写的一个IM框架,它给Mac和iOS提供了易于使用的.强大的异步套接字库,向上封装 ...
- iOS可视化动态绘制连通图
上篇博客<iOS可视化动态绘制八种排序过程>可视化了一下一些排序的过程,本篇博客就来聊聊图的东西.在之前的博客中详细的讲过图的相关内容,比如<图的物理存储结构与深搜.广搜>.当 ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- iOS总结_UI层自我复习总结
UI层复习笔记 在main文件中,UIApplicationMain函数一共做了三件事 根据第三个参数创建了一个应用程序对象 默认写nil,即创建的是UIApplication类型的对象,此对象看成是 ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- 告别被拒,如何提升iOS审核通过率(上篇)
iOS审核一直是每款移动产品上架苹果商店时面对的一座大山,每次提审都像是一次漫长而又悲壮的旅行,经常被苹果拒之门外,无比煎熬.那么问题来了,我们有没有什么办法准确把握苹果审核准则,从而提升审核的通过率 ...
随机推荐
- Octave下操作CH341
#include <octave/oct.h> #include <windows.h> #include <cstdint> #include <fstre ...
- 我所遭遇过的游戏中间件--Havok
我所遭遇过的游戏中间件--Havok Havok是我接触的第一款游戏中间件,那是在五,六年前,我刚刚毕业,对游戏开发还是个菜鸟.我记得先是对游戏场景中的地形和其他静态物体生成刚体,然后做角色的Ragd ...
- 第七章 常用Java集合类总结
7.1.List(允许重复元素) ArrayList: 底层数据结构:Object[] 在查询(get).遍历(iterator).修改(set)使用的比较多的情况下,用ArrayList 可扩容,容 ...
- 网站流量分析指标-PV/UV/PR/IP
网站数据分析,经常会统计一个页面或者一个网站或者其他情况的PV/UV.下面简单说一下,这些量PV/UV/PR/IP. 1.PV PV(page view),即页面浏览量,或点击量.通常是衡量一个网络新 ...
- Android之SlideMenu实例Demo
年末加班基本上一周都没什么时候回家写代码,回到家就想睡觉,周末难得有时间写个博客,上次写了一篇关于SlideMenu开源项目的导入问题,这次主要讲讲使用的问题,SlideMenu应用的广泛程度就不用说 ...
- 网上收集:跟着 8 张思维导图学习 Javascript【转】
学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...
- Transform开发cube模型权限处理之不同用户数据的过滤
========================此文不再详细的说transform的开发过程====================================================== ...
- 相似qq的IM聊天应用源代码
这个是IM聊天应用源代码,该应用IM支持实现XMPP,以及图片和表情,语音.消息回执等功能,基本覆盖了常见的im应用的功能了,大家能够參考一下吧. 源代码下载:http://code.662p.com ...
- 大型应用的javascript架构
来源:http://blog.leezhong.com/tech/2010/11/29/javascript-arch.html 目前很多网站基本没有明确的前端架构,大多是服务端渲染视图页,输出到浏览 ...
- IDEA+Gradle相关资料
要注意下载的版本,不能过于陈旧,否则会报错,导致无法正常配置. 具体配置参考:https://my.oschina.net/u/1994816/blog/297967 IDEA下载地址:https:/ ...