因为实习原因很久不更新了... 很多东西经常不记也就忘记了,下次再需要的时候还得继续google之, 于是把最近遇到的一些问题记录下来.
开始实习以后,ruby 学了一半开始搞php,php学了一半开始搞android,现在又开始ios
什么都学了一点,了解一点,但是不深... 这是个较大的问题
算,这说明我学习能力还不错...
言归正传,还是总结ios 吧
__________________________________________
刚开始接触ios, 主要要从以下几个部分入手, 弄清楚一下几个部分也就能写出一个较容易的APP了:
1. UI 界面 设计
2. 数据存储
3. 网络连接
1.UI 界面设计
ios 的页面 主要有两种实现方式 xib 和 storyboard (故事版).
storyboard, 顾名思义, 他将很多个xib 整合在一起, 你可以看到一个全局的界面, 并了解不同页面之间是如何跳转和关联的
缺点是不支持ios5.0一下, 并且当你的app 页面较多且复杂时不太适合, 可以考虑storyboard 和 xib 结合的方式
xib, 了解android 开发的人可以把它看成是一个layout, 而 android 中的 acitivity 则对应于ios 中的 viewcontroller
android 中一个acitivity 对应一个 layout, ios 中 一个viewcontroller 对应一个 xib
ios 中不像 android 中提供了 不同的布局方式, 简单的布局只需要将控件拖动到xib上即可.
控件的监听事件只需要拖动并关联即可.
常用的方式主要有 navigationController 和 tabbarController, 可以相互嵌套并嵌套多个,类似设计模式中的装饰模式.
需要注意的一个点是navigationController 维护的是一个 栈 , 只能通过push pop 的方式将操作viewcontroller 跳转到下一个页面
或者通过 presentModalViewController 跳转到下一个页面
view controller 的生命周期
如图所示, 当 viewDidLoad 只会在创建该页面时调用一次, viewWillAppear 和 viewDidAppear 则会在每次该页面出现时调用
可以看成 android 中的 onCreate 和 onResume
2. 数据存储
ios 文件系统中,每个App都有一个独立的home 目录, 目录结构如下
/Appname.app 包含app本身,内含app的所有资源以及可执行文件, app 不允许修改此目录下的文件.
/Documents 关键数据和app数据,比如plist 和 sqlite 文件
/Library 存放非用户数据
/tmp 存放不需要在app每次启动都保持的数据,临时文件. 系统可以删除其中的内容以释放空间
我主要用到的存储方式有两种 : 1. key -value 存plist 文件 2. core data 对sqlite3的一层封装, 保存结构化的数据
3.网络连接
网络连接主要用到了开源的 AFNetworking, 在demo 中可以了解最近基本的网络连接方法。
这里主要介绍一下如何进行https 的访问 和 timeout 延时设置
AFNetworking 的 https: (默认信任所有)
创建类 XXXOperation 继承于 AFHttpRequestOperation, 实现如下方法即可:
- (id)initWithRequest:(NSURLRequest *)urlRequest{
[self setAuthenticationAgainstProtectionSpaceBlock:^BOOL(NSURLConnection *connection, NSURLProtectionSpace *protectionSpace) {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}];
[self setAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}];
return [super initWithRequest:urlRequest];
}
通常我们通过setTimeOut 方法设置超时时间,但在ios中, 即使你修改了该值, timeout 最小为240s.
有两种解决方案:
1 修改 访问方式为 GET, 即可成功修改timeout值
2.新建计时器当操作延时后, cancel 掉该操作,具体实现如下:
#pragma mark -
#pragma mark override, timeout
+ (void)setDefaultTimeOutInterval:(NSTimeInterval)timeout {
DebugLog(@"defaultTimeoutInterval set to:%f", timeout);
defaultTimeoutInterval = timeout;
}
- (NSTimeInterval)timeoutInterval {
if (timeoutInterval > 0) {
return timeoutInterval;
}
return defaultTimeoutInterval;
}
- (void)start {
NSTimeInterval timeout = self.timeoutInterval;
if (timeout > 0) {
timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:timeout target:self selector:@selector(timeout:) userInfo:nil repeats:NO];
}
[super start];
}
- (void)timeout:(id)sender {
if (![self isFinished] && ![self isCancelled]) {
cancalledBecauseOfTimeout = YES;
[self cancel];
}
[timeoutTimer invalidate];
timeoutTimer = nil;
}
同时, 新增接口, setCompletionBlock, 增加 cancel 的处理段(由于原来的代码已经成型, 不想做太多改动增加工作量, 只好想出这么个恶心的办法了, 还算好用)
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure cancel:(void (^)(AFHTTPRequestOperation *, NSError *))cancel{
self.completionBlock = ^{
if ([self isCancelled]) {
dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{
cancel(self, self.error);
});
}
else if (self.error) {
if (failure) {
dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{
failure(self, self.error);
});
}
} else {
if (success) {
dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{
success(self, self.responseData);
});
}
}
};
}
暂时就这么多, 还有问题以后继续补充