最快入门ios开发-第三,四天

    第三,四天,主要是针对几个典型的应用编写相关代码。虽然说前面看过sample code,研究过一些语法,但是真正上手写时仍然是举步维艰,可能一句话就能解决的问题往往要查上很久,但是个人认为这种方式也比较快,往往针对问题。至于研究得深入不深入,就要看时间够不够了,我觉得要在初学时候所有东西都深入研究还是有一定难度的,但是一些常见的应该要深入进去。

    1. HTTP访问web,目标是封装成为一个今后也可以使用的通用类库。下面就是一个asihttprequest的restful的例子,由于未完全理解objective-c的东西,估计还有更好的方式。需要明白,安装一个类库一般需要拷贝头文件,添加链接类库几个步骤,如果是在ARC的环境中,还要到build phases中手动将手动引用计数的文件的编译标志中加上一个-fno-objc-arc

#import "HttpClient.h"
#import "ASIHTTPRequest.h"
#import "ResponseProcessDelegate.h"

@implementation HttpClient

NSString * configParam(NSString * template, NSDictionary * param){
    NSString *result;
    for(NSString * key in [param allKeys]){
        result = [template stringByReplacingOccurrencesOfString:key withString:[param objectForKey:key]];
    }
    return result;
}

- (void) get:(NSString *)url with:(HttpRequestParam *) param responseDelegate:(id<ResponseProcessDelegate>) delegate{
    sendRequest(url,nil,param,@"GET",delegate);
}

- (void) post:(NSString *)url and:(NSMutableString *)body with:(HttpRequestParam *) param responseDelegate:(id<ResponseProcessDelegate>) delegate{
    sendRequest(url,body,param,@"POST", delegate);
}

void sendRequest(NSString * url, NSString * body, HttpRequestParam * param, NSString * method, id<ResponseProcessDelegate> delegate){
    if(param != nil && param.requestParam){
        url = configParam(url,param.requestParam);
    }
    NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
    NSString *requestUrl = [NSString stringWithFormat:@"%@://%@:%@/%@",[defaults objectForKey:@"protocol"], [defaults objectForKey:@"server"], [defaults objectForKey:@"port"], url];
    
    NSURL *actualUrl = [NSURL URLWithString:requestUrl];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:actualUrl];
    NSLog(@"send request:%@:", requestUrl);
    [request setTimeOutSeconds:1000];
    if([method isEqualToString:@"POST"]){
        [request setRequestMethod:@"POST"];
        if(param != nil){
            body = configParam(body,param.bodyParam);
        }
        if(body != nil){
            [request appendPostData: [body dataUsingEncoding:NSUTF8StringEncoding]];
        }
    }else{
        [request setRequestMethod:@"GET"];
    }
    [request setCompletionBlock:^{
        NSString *responseString = [request responseString];
        [delegate success:responseString withParam:param];
        NSLog(@"%@%@", @"request success",responseString);
    }];
    [request setFailedBlock:^{
        NSLog(@"%@%d%@", @"request failed",[request responseStatusCode], [request responseHeaders]);
        [delegate fail];
    }];
    [request startAsynchronous];
}

@end

    随着研究的深入,发现这种写法并不是一种比较好的调用方式,因为需要在每个controller的实现中添加success和fail这两个delegate,比较好的做法是用block,于是有了下面的代码。

- (void) get:(NSString *)url
   onSuccess:(VoidBlock) successBlock
     onError:(ErrorBlock) errorBlock{
    sendRequest(url,nil,successBlock, errorBlock);
}

- (void) post:(NSString *)url
         body:(NSMutableString *)body
    onSuccess:(VoidBlock) successBlock
      onError:(ErrorBlock) errorBlock{
    sendRequest(url,body,successBlock, errorBlock);
}

void sendRequest(NSString * url,
                 NSString * body,
                 VoidBlock successedBlock,
                 ErrorBlock errorBlock){
    NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
    NSString *requestUrl = [NSString stringWithFormat:@"%@://%@:%@/%@",[defaults objectForKey:@"protocol"], [defaults objectForKey:@"server"], [defaults objectForKey:@"port"], url];
    NSURL *actualUrl = [NSURL URLWithString:requestUrl];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:actualUrl];
    NSLog(@"send request:%@:", requestUrl);
    [request setTimeOutSeconds:10];
    if(body != nil){
        [request appendPostData: [body dataUsingEncoding:NSUTF8StringEncoding]];
        [request setRequestMethod:@"POST"];
    }else{
        [request setRequestMethod:@"GET"];
    }
    [request setCompletionBlock:^{
        NSString *responseString = [request responseString];
        successedBlock(responseString);
//        NSLog(@"%@%@", @"request success",responseString);
    }];
    [request setFailedBlock:^{
        NSLog(@"%@%d%@", @"request failed",[request responseStatusCode], [request responseHeaders]);
        errorBlock([request error]);
    }];
    [request startAsynchronous];
}

    其中,block的定义如下

typedef void (^VoidBlock)(NSString *response);
typedef void (^ErrorBlock)(NSError *error);

    2. 应用设置,应当知道如何在应用程序里做设置以及读取设置。

    ios中设置非常简单。只需要在根目录new File->Resource->Settings Bundle,即可生成一个Settings.bundle,这个文件可以表示setting中的各种控件,比如Test field,Switch等等。简而言之,你只需要配置这个bundle,其他的显示通通由ios自己搞定。真是简单啊。

    而读取只需要操作单例类NSUserDefaults,初始如下调用,接下来就可以像操作NSDictionary一样使用它。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults objectForKey:@"port"];

    但是有个坑,读取默认配置,可能你会认为设置了Default value,它随后就会读出来,实际情况是默认配置跟真正的值没有关系。也就是说,你第一次读取出来的值是null。

    查了一下,最佳实践应该是这样,在appDelegate的didFinishLauchingWithOptions中(还记得生命周期图吗)添加如下方法,查了一下AppPrefs的sample code,原来人家也是类似的做法:

NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]
NSString * port = [defaults objectForKey:@"port"];
if(!port){
    port = @"8888";
}
NSDictionary *defaultValues = [NSDictionary dictionaryWithObjectsAndKeys:port, @"port",nil];
[[NSUsertDefaults standardUserDefaults] registerDefaults:defaultValues];

    3. 简单控件的使用,比如TextField, Button,以及控件自定义,比如自定义开关。

    关于简单控件的使用,参考第一天的storyboard入门一节的文章,照着那个做,基本上简单控件和流程就有个数了。

    一个比较牛的自定义开关,可以自定义文字,大小等等

http://code4app.com/ios/Customized-Round-Switch/4f6d915b6803faef27000000

    4. 2维图形和动画的使用。

    http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/

    http://www.189works.com/article-86565-1.html

    画圆带边的两种方式:

    4.1 贝塞尔曲线

UIBezierPath * bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(x, y) radius:REDIUS startAngle:0 endAngle:2 * M_PI clockwise:1];
    [[UIColor whiteColor] setFill];
    [bezierPath closePath];
    [bezierPath fill];

    4.2 arc

CGContextMoveToPoint(context, x, y);
    CGContextSetRGBFillColor(context, 1, 1, 1, 1.0);
    CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
    CGContextSetLineWidth(context, 0.6);
    CGContextAddArc(context, x, y, REDIUS, 0, 2 * M_PI, 1);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathEOFillStroke);

    5. 手势和事件的使用。

    ios手势在模拟器中的快捷键

tap          触屏点击
swipe        触屏按下后扫过并松开
pinch        option按下后出现两个圆球,拉远他们就是放大,反之缩小
rotation     option按下后出现两个圆球,触屏按下并旋转


     6. 在例子编写中犯的一些问题。

     通常这类问题很傻很天真,但是我相信背后能揭示一定的东西

     1) 我采用storyboard开发,最初添加了一个loadView方法,里面控制画了地图,显示得很好。接着我又在storyboard拖拽了几个view和其他控件上去,把地图显示的代码注释掉。再运行就黑屏,打印出来一句Application windows are expected to have a root view controller at the end of application launch。于是我就漫无目的的找啊找啊,先是找到要添加rootViewController的方法http://www.jnhctt.com/kf/201202/120864.html,加了半天发现不对,于是又找,才知道我用storyboard实际上是不需要加这些的,storyboard会帮你完成,可能是plist中Main storyboard file base name这条不见了,一看也在,于是又找到说是summary中main storyboard这里没填,一看填了。这时候有点小崩溃了。花了近半天时间啊。最后终于在某个问题的边角回复中发现原来loadView方法也会导致这个问题,崩溃。最开始收集的view的生命周期也没讲到这个,看起来还要不断的试错才行啊。

      2) 第二个问题是直接崩溃的,报错this class is not key value coding-compliant for the key tableView。发现主要原因是之前注释了IBOutlet的属性代码,但是界面上还保留着这些已经连线的IBOutlet,界面找不到配对的属性于是报错,修改办法就是恢复注释掉的IBOutlet属性。

      3) 布局问题,出现过好几个布局问题,其中一个是UIView中的子view很大,通过constraint限制四边的边距貌似不起作用,找了半天,发现菜单栏的Editor中的pin可以constraint指定宽和高,于是定下了宽高,解决问题。另一个是用程序将一个view加入container view中,我希望他们两size一样,但是无论如何都要窄一些,又捣腾了半天,发现其他方法貌似都不管用,通过设置子view的bounds=父view的bounds就轻松解决,真是坑爹啊。

      4) 警告,format string is not a string literal (potentially insecure) ,新版的NSLog改成了只接受格式化的字符串,于是,格式就要类似这样

NSLog(@"%@", (NSString *)str);


     7. 关于地图。

     7.1 google map。google map的api是我用过的比较好用的api了,简洁快速,基本上照着官方一个简单的流程走下来就ok了。https://developers.google.com/maps/documentation/ios/start 

          但是我还是犯了两个菜鸟级错误:一是Other Linker Flags没有设置,报错为unrecognized selector sent to instance;二是Api_key没有生效(注意修改后bundle id后要过一段时间才生效,这时不如直接删掉重新添加),报错为Error Domain=com.google.HTTPStatus Code=400。
          另外,google map的api比较简单,一个是设置cam的经纬度(即中心位置,参考中国各个城市经纬度http://hi.baidu.com/sunbolg/item/63f77439f6e5a580b611db5c),然后设定缩放级别,从小到大依次放大


     7.2 Mapkit这个地图也不错。这里推荐一个sample,将mapkit和动画等等一网打尽。http://www.oschina.net/p/Thumbnail-Annotation,这里有篇关于overlay的文章http://www.raywenderlich.com/30001/overlay-images-and-overlay-views-with-mapkit-tutorial


swift书

http://download.csdn.net/album/detail/77

Cocos2dx书

http://download.csdn.net/album/detail/81

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值