2012年11月30日 星期五

iOS IPA with sign on command Line

http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution

http://stackoverflow.com/questions/2664885/xcode-build-and-archive-from-command-line

還沒有研究  先記錄

iOS 各個Model 的型號

http://theiphonewiki.com/wiki/index.php?title=Models

各個 model的型號

2012年11月26日 星期一

2012年11月24日 星期六

iOS UIWebview


http://www.cocoachina.com/applenews/devnews/2012/1123/5167.html


有空再來看看哪些可以偷來用@@!

iOS 小技巧?!



http://www.cocoachina.com/applenews/devnews/2012/1123/5166.html


有些看起來還蠻有趣的!


1、Xcode调试技巧—在系统抛出异常处设置断点
有时候我们的程序不知道跑到哪个地方就 crash 了,而 crash 又很难重现。
保守的做法是在系统抛出异常之前设置断点,具体来说是在 objc_exception_throw处设置断点。
设置步骤为:首先在 XCode 按 CMD + 6,进入断点管理窗口;
然后点击右下方的 +,增加新的 Symbolic Breakpoint。
在 Symbol 一栏输入:objc_exception_throw,然后点击 done,完成。
这样在 Debug 模式下,如果程序即将抛出异常,就能在抛出异常处中断了。
比如在前面的代码中,我让 [firstObjctcrashTest]; 抛出异常。在 objc_exception_throw 处设置断点之后,程序就能在该代码处中断了,我们从而知道代码在什么地方出问题了。

2、计算UIlabel 随字体多行后的高度
+ (CGFloat)calcTextHeight:(int)textWidth text:(NSString *)text font:(int)fontSize {
    CGRect bounds, result;
    bounds = CGRectMake(0, 0, textWidth, 300);
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
    label.font = [UIFont systemFontOfSize:fontSize];
    label.text = text;
    result = [label textRectForBounds:bounds limitedToNumberOfLines:20];
    return result.size.height;
}

或者CGSize requiredSize = [introduceLabel.text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(296.0f, FLT_MAX) lineBreakMode:UILineBreakModeTailTruncation];

3、计算当前label随字体增加的长度(单行)
CGSize boundingSize = CGSizeMake(320.0f, CGFLOAT_MAX);
CGSize requiredSize = [status.user.username sizeWithFont:[UIFont boldSystemFontOfSize:13] constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat requiredWidth = requiredSize.width;


4、view控件加边框
profileImageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[profileImageButton.layer setMasksToBounds:YES];
[profileImageButton.layer setCornerRadius:4.0]; //设置矩形四个圆角半径
[profileImageButton.layer setBorderWidth:1.0];   //边框宽度
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef colorref = CGColorCreate(colorSpace,(CGFloat[]){225.0/255.0, 225.0/255.0, 225.0/255.0, 1.0 });
[profileImageButton.layer setBorderColor:colorref];//边框颜色

单独设置圆角
[iconImage.layer setCornerRadius:4.0];
[iconImage setClipsToBounds:YES];

5、时区返回格式为数字(-12—+12)  
-(NSString *)getTimeZone{
    NSString *zone = [[NSTimeZone systemTimeZone] description];//Europe/Berlin//       America/New_York//   Asia/Harbin
                                                                               //这三个可以用来测试exp:NSString *zone = [[NSTimeZone timeZoneWithName:@"America/New_York"] description];
    NSString *time = [[zone componentsSeparatedByString:@"offset "] objectAtIndex:1];
    int inv = [time intValue];
    int result = inv / (60 * 60);
    if (result>0) {
        return [NSString stringWithFormat:@"+%d", result];
    }
    return [NSString stringWithFormat:@"%d", result];
}

6、判定输入框不为空格以及空
   NSString *_textField=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([_textField length] == 0) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"" message:@"评论内容不能为空!" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alertView show];
        return NO;
    }


7、根据当前键盘的高度来设置UITextField的位置
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)keyboardWillShow:(id)sender {
    CGRect keyboardFrame;
    [[[((NSNotification *)sender) userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
    CGFloat keyboardHeight = CGRectGetHeight(keyboardFrame);
    [self.textImageView setFrame:CGRectMake(0, 416-keyboardHeight, 320, 45)];
}
8、设置label ,imageview,等点击时事件
    UITapGestureRecognizer *imageTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImage:)];
   // [imageView setUserInteractionEnabled:YES]; 如果不能点击,设置可编辑
    [imageView addGestureRecognizer:imageTap];

9、判断剩余字数(字母数字符号两个算一个汉字)
-(int)charNumber:(NSString *)strTemp
{
    int strLength =1;
    char *p =(char *) [strTemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0; i<[strTemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding]; i++)
    {
        if (*p) {
            p++;
            strLength++;
        }
        else{
            p++;
        }
    }
    return strLength/2;
}

10、UIWebView加载gif图片  ——这样可以解决gif图片不能下载到本地加载,使用SDWebImage down也出现界面不流畅,卡的问题
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, [homeTableCell getImageWidth:funnyPic], [homeTableCell getImageHeight:funnyPic])];
        webView.backgroundColor = [UIColor clearColor];
       // webView.scalesPageToFit = NO; 这一句我一直没搞清楚,有时对,有时不对的,注释了吧
        //禁止webView的滑动 这样写主要是因为5.0以前的系统不能直接获取到webView.scrollView
        [(UIScrollView *)[[webView subviews] objectAtIndex:0] setBounces:NO];
// 不让有白色的边,这个margin是必须的  
        NSString *html = [NSString stringWithFormat:@"<html><body style=\"margin: 0px;\"><img src=\"%@\"></body></html> ",funnyPic.imageUrl];
        [webView loadHTMLString:html baseURL:nil];
        [imageView addSubview:webView];

11、插入加载更多 tableview reloadData闪的问题
        if (requestArray && [requestArray count] > 0) {
            int cellCount = [requestArray count];//获取一共有几行
            NSMutableArray *indexArray = [[NSMutableArray alloc]initWithCapacity:10];
            int numCountNow = [self.tableView numberOfRowsInSection:0];
            for (; cellCount > 0; cellCount--) {
                NSIndexPath *path = [NSIndexPath indexPathForRow:numCountNow + cellCount - 1 inSection:0];
                [indexArray addObject:path];
            }
            [self.tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
        }

12、Image 加载16进制的 图片(编译成freamwork的时候不能直接加载png图片,要转化)
首先,使用UltraEdit把图片转化为16进制
static const char _playerPause_icon [] = {
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
    0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1B, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0xF6, 0x64,
    0x9C, 0x00, 0x00, 0x00, 0x39, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8D, 0x63, 0x64, 0x60, 0x60, 0x38,
    0xC3, 0x80, 0x1D, 0x98, 0x60, 0x11, 0xC3, 0xAA, 0x96, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1, 0x4A,
    0x30, 0x32, 0x32, 0xA2, 0x8B, 0xE1, 0x52, 0xCB, 0x84, 0xC3, 0x15, 0x24, 0x81, 0x51, 0x43, 0x46,
    0x0D, 0x19, 0x35, 0x64, 0xD4, 0x90, 0x51, 0x43, 0x46, 0x0D, 0xA1, 0xA7, 0x21, 0x00, 0xDD, 0x84,
    0x09, 0xFD, 0x6B, 0x3C, 0x1F, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42,
    0x60, 0x82
};
然后加载
[playButton setImage:[UIImage imageWithData:[NSData dataWithBytes:_playerPause_icon length:sizeof(_playerPause_icon)/sizeof(char)]] forState:UIControlStateNormal];

13、倒计时(剩余时间)
- (void)timerFireMethod:(NSTimer*)theTimer{
    
    id obj = [theTimer userInfo];
    NSDateFormatter *f1 = [[NSDateFormatter alloc] init];
    [f1 setDateFormat:@"yyyy-MM-dd HH:mm:ss.S"];
    
    NSDate *theDay = [f1 dateFromString:(NSString*)obj];
    [f1 release];

    NSCalendar *cal = [NSCalendar currentCalendar];//定义一个NSCalendar对象
    
    NSDate *today = [NSDate date];//得到当前时间
    
    //用来得到具体的时差
    unsigned int unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDateComponents *d = [cal components:unitFlags fromDate:today toDate:theDay options:0];
    
    NSString *countdown = [NSString stringWithFormat:@"%d日%d时%d分%d秒", [d month],[d day], [d hour], [d minute], [d second]];
    
    self.timeLabel.text = countdown;
    return ;
    
}

14、九宫格或者其他类型的坐标设置
        frame.size.width = 60;//设置按钮坐标及大小
        frame.size.height = 60;
        frame.origin.x = (i%3)*(60 + 32)+40;
        frame.origin.y = floor(i/3)*(60 + 24)+60;

2012年11月22日 星期四

git branch

http://blog.wu-boy.com/2011/03/git-%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6-branch-model-%E5%88%86%E6%94%AF%E6%A8%A1%E7%B5%84%E5%9F%BA%E6%9C%AC%E4%BB%8B%E7%B4%B9/


http://gogojimmy.net/2012/01/21/how-to-use-git-2-basic-usage-and-worflow/

嘗試利用  branch .....


現在簡單應用下面的指令


直接由 develop 開出分支 myfeature,並且直接切換過去
git checkout -b myfeature develop
# 直接下 git branch 觀看目前位置
  develop
  master
* myfeature
經過編輯修改並且 commit
git add test.php
git commit -a -m "Add: test.php"
合併分支:
先切換到 develop
git checkout develop
Switched to branch 'develop'
利用 –no-ff 合併分支(稍後說明為什麼使用 –no-ff)
git merge --no-ff myfeature
Merge made by recursive.
 test.php |    3 +++
 1 files changed, 3 insertions(+)0 deletions(-)
 create mode 100644 test.php



2012年11月21日 星期三

Jenkins + Unit Test



掙扎了一陣子

後來決定用  GHUnit + OCMock + OCHAMCREST

(下午遇到的問題是....可能要先在自己的mac上 make過 framework才能跑 我猜是 SDK的問題)

接著可能要解決的問題

1. ghunit 的 templete file

2.  INSTALL OCMock + OCHAMCREST

3.  run on the Jenkins

4.  以及最重要的..... 究竟要怎樣使用qq


他有遇到的我也有遇到耶!
http://www.egeek.me/2012/10/03/jenkins-ghunit-launch-msg-error/



Jenkins + GHUnit

http://www.tuicool.com/articles/uUbuUn

http://gabriel.github.com/gh-unit/docs/appledoc_include/guide_command_line.html

http://gabriel.github.com/gh-unit/docs/appledoc_include/guide_ci.html


======================================



一直卡在最後出 report 的地方

後來想說還是用官方的  OCUnit

感覺整合性還是好很多

再配合  OCUnit2JUnit

應該會不錯用


繼續努力....orz


http://www.raingrove.com/2012/03/28/running-ocunit-and-specta-tests-from-command-line.html

要先多建立一個 scheme

然後設定其關連性

script 用  https://gist.github.com/2410839

用 系統內的好像會一直出問題  (系統內好像是新的 anyway  至少舊的可以用....)


最後再 jenkins 上面的指令用:
xcodebuild -workspace xxxxx.xcworkspace -scheme xxxxx -sdk iphonesimulator5.1 -configuration Debug TEST_AFTER_BUILD=YES clean build


iphonesimulator5.1   不用 iphonesimulator   這樣預設好像是會用  6.0  好像會有 顯示視窗大小的問題....



finally .....  我一直放錯重點  明明應該是要好好寫 Unit test  ,  卻一直放在產生 report 上

搞了一個下午+晚上+隔天早上  ....  終於弄出一個至少可以用的orz

時間真不夠用...QQ



other ref

http://www.gerardcondon.com/blog/2012/09/20/further-jenkins-setup-code-signing/

http://www.stewgleadow.com/blog/2012/02/09/running-ocunit-and-kiwi-tests-on-the-command-line/

http://hataewon.tumblr.com/post/30045666799/how-to-use-subprojects-with-xcode-and-jenkins

http://hataewon.tumblr.com/post/30327012898/continuous-integration-for-cocoa-using-jenkins-part-ii



Unit test  example ?!?!

https://github.com/iamleeg/BrowseOverflow/tree/master/BrowseOverflowTests



2012年11月20日 星期二

Jenkins setting

http://jdonee.iteye.com/blog/315440


雖然是舊?!  不過有些可能之後可以設定看看



  • Project name :我已经把这个项目命名为HeliosJMXTrunk ,但你也可以在这里修改它。
  • Description : 这是一个自由项,主要用来说明你关于这次构建工作的描述。可不填。(帮助:这说明放在项目的首页,以便访问者可以知道这个工作的内容。您也可以在这里使用任何HTML标记。)
  • Discard old builds : Hudson默认将保留过去的构建,除非你事先选中此框。(帮助:这里控制着您想要在Hudson所在的磁盘把构建记录存储的有效期(诸如控制台输出、编译构件等等)。Hudson为此提供了两个标准:1。时间驱动。在Hudson中您可以判断如果达到一定时限来删除一条记录(例如,七天前)。2。数量驱动。在Hudson中您可以确保它拥有N份构建。如果又有新的构建开始,最早的那份(记录)就将被删除。Hudson也可以让您建立的个别构建定义为'永远保持这个记录',以便防止某些重要的构建被自动丢弃。)
  • This build is parameterized : 如果选择此选项,Hudson将允许您提供一套任意的键值对参数,它们会被传递到构建过程里。配置的参数往往是构建运行环境中的一些环境变量。(帮助:当您使用了Hudson的各种自动化,有时要求在构建过程中提供一组用户的输入,使用“parameterize”就能够更方便构建。例如,您可能会设立一个按需测试,在那里用户可以提交一个二进制文件的压缩文件来进行测试。
    本节参数可以完全按照您构建的需要配置。参数是以名字区分的,所以您可以有多个参数,只要它们名称不同。
    关于此功能的更多资料请查看维基专题讨论 。)
  • Enable project-based security : Hudson支持全面的安全方案,可以强制用户在通过身份验证后,再访问Hudson网页;它也可以通过控制用户的权限来管理用户的工作。在这个Hudson例子中我没有配置安全 [你可以参考我的另外两篇文章:Use Hudson之标准安全设置使用matrix security对Hudson进行细粒度Job的安全控制,获取关于安全的详细配置]。
  • Disable build : 如果这里被勾选,这项工作将不会执行构建,直到选项禁用为止。(帮助:有时候,你会想暂停某个构建中的项目。例如,也许您正准备一次大的迁移,而且你知道新版本会失败。或者您想每一个小时构建一次,但您却发现CVS服务器将在未来24小时内down机。当这个选项被设置后,关于这个项目就不会再有新的构建。这样一来,您就可以在不想改变外部依赖或者提交错误通知的情况下禁用构建过程。)
  • Advanced options : 我没有使用这些选项,但是当此复选框被选中时,选项中就会暴露下面的接口:
    • Quiet period : 在这里您可以配置一个静态监控,当构建准备按某个计划运行时,实际上它就已经在开始执行了。
    • Use custom workspace : 默认情况下,Hudson将在${jboss-home}/.hudson/jobs/[项目名称](注:Linux环境 )下创建一个工作区 。此选项将允许您使用指定的地址替代(它)。
  • Source code management : 在默认情况下是这三个选项:
    • Subversion
    • CVS
    • None
        这个None会误解我先前的主张 :一个先决条件是要有一个源代码仓库。但我坚持认为,在大多数情况下,为Hudson选择某个仓库是绝对必要的。本文稍后,我将讨论如何安装Hudson插件。如果您安装了一个与SCM相关的插件,并重新启动Hudson,那么在这个清单上也将出现一些新的选择。本文,我使用 Subversion 。当您选择Subversion后,将展开一个配置表单。我会在下面的某一部分中单独描述这个配置(见“ Subversion的工作配置” ) 。
  • Build after other projects are built : 此选项支持一条装配(流水作业)线——作业依赖: 一个作业依赖于另一个作业的输出的情况 —— 或者如以下情形:你只是想简单的把一些有关的工程构建编入一个组以便一起构建。当您一选择它,你将得到一个字段,输入其他工程的名字[多个项目名间用逗号分隔]后,这个构建应该就可以运行。
  • Poll SCM : 这是CI 系统中常见的选项。当您选择此选项,您可以指定一个定时作业表达式来定义Hudson每隔多久检查一下您源代码仓库的变化。如果发现变化,就执行一次构建。例如,表达式中填写0,15,30,45 * * * *将使Hudson每隔15分钟就检查一次您源码仓库的变化。更多信息请查阅Quartz CronTrigger中关于这个定时作业语法的详细描述(新版Quartz支持从秒开始触发,所以请查阅下面的cron帮助,对此引起的误导表示歉意)。
  • Build periodically : 此选项 (也是使用定时作业表达式)仅仅通知Hudson按指定的频率对项目进行构建,而不管SCM是否有变化。我这个作业就属于目标测试环境是按某种方式定期修订的而SCM却是静态的情况。如果您想在这个作业中运行一些测试用例的话,它可能就很有帮助。
  • Add build step : 按一下这个按钮,添加了一项指令以执行构建脚本。您的指令可以是下列之一:
    • 执行 Shell
    • 执行 Windows 批处理
    • 使用Ant(这是我将要使用的选项,在下面我会做详细的说明)
    • 使用Maven
  • Archive the artifacts : 当您选择此选项,就可以指定文件和目录的掩码(Ant风格的掩码,可以指定包含与排除),当与掩码相匹配的构件在构建时将被添加到Hudson的构件仓库,它们会用作业(名)和构建序号来标识。所有以前构建过的构件可以选择性地丢弃,以节省您Hudson服务器上的磁盘空间。
  • Record fingerprints of files to track usage : 当您选择此选项,它使用类似Ant方式的掩码,恁可以指示Hudson去生成构件的指纹码,确保您能够更容易地找到它们的位置,另外判断系统中的这些构件是否还在使用。
  • Publish javadoc : 如果您的构建脚本能生成JavaDoc,此选项将指示Hudson发布这些内容,而且立即把它公布在当前工作的主页上。每一个成功构建的文档内容都可以保留,但在默认情况下只保留最新的。
  • Publish JUnit test result report : 如果您的构建脚本执行了JUnit测试,此选项将指示Hudson处理XML测试文档并为每次连续构建产生一份可持续的报告,依据正在进行的测试汇总处理结果。其结果是当前工作主页的一份报告,作业中的单元测试会随着时间的推移按由老至新进行陈列。
  • Aggregate downstream test results : 在某些情况下,作业中一组单元测试花费的时间大大长于实际构建它所花的时间。在这些情况下,你可以选择把构建和测试分为不同的作业,以便完成构建能相对迅速,一旦与这相关的一个或多个测试作业就执行完毕,构建也就成功完成了。 当您选择这个选项, Hudson就会把构建后作业的测试结果进行统计,并且能追溯到它们的明细。用以做为本次构建成功或失败的主要依据。
  • Build other projects : 较之前面的选项,这个选项主要用来实现一个合乎逻辑的构建和测试过程,它会被分为两个或两个以上的物理工作,并且会按顺序执行。当此项被选择后,您将得到一个字段,可以在其中输入您想在当前作业中后执行的其它作业名[多项作业可用逗号分隔]。即使目前的作业得出结论说构建可能不稳定,您也可以选择这样做。(关于“作业的稳定性”请查阅“作业状态”章节以获取更多信息)
  • E-mail notification : 当您选择此选项,您可以输入一个或多个电子邮件地址[多个可用空格分隔],当Hudson完成了执行作业后,将会给它们发送通知。事件触发时将产生一份Email,包括构建失败、构建不稳定等。这儿有一个额外的选项,当由于用户的错误提交造成Hudson决定废弃此次构建,将会发送一份专门的邮件给这位SCM提交者,以便让他检查源代码。

iOS 6 要注意的差異點



http://my.oschina.net/vimfung/blog/79787



1、适配4英寸屏幕适配。

旧应用要与4英寸屏幕进行适配,需要创建一张Default-568h@2x.png图片,系统根据是否有此资源来识别是否支持4英寸屏幕。至于其他资源不允许使用xxx-568h.jpg此格式来适配屏幕,需要使用代码对屏幕进行检测来分别进行适配。


2、UINavigationViewController的变化

今天开发过程中发现的,该类的initWithRootViewController在之前的版本是最终会调用到init方法的。因此在继承UINavigationViewController时,直接在重写init方法来初始化对象所需属性即可。但是在iOS6上是不会调用init方法,因此需要开发者们注意。

3、CFRelease的变化

在之前版本中如果CFRelease传入nil是被允许的,这也符合我们传入nil对象不会对我们的程序造成影响,但是在iOS6中,这样的写法程序就直接把你的程序Crash掉了,所以代码中还是需要判断一下是否为nil才是安全的做法。


4、UIPickerView的变化

在之前版本中调用[_pickerView selectRow:-1 inComponent:0 animated:YES];是允许的。但在iOS6中会导致崩溃。

5、UIActivityIndicatorView的变化

在之前的版本中假如调用了startAnimating方法之后,只要把UIActivityIndicatorView添加到子视图中就会显示加载动画,但在iOS6中只要移出显示队列则会停止动画,特别在UITableViewCell中加入此控件,只要滚动几下Cell的UIActivityIndicatorView就消失了,为解决此问题可以在加入显示队列时根据isAnimating属性来判断是否执行动画,如果没有则重新调用一下startAnimating方法。

6、通讯录列表获取差异

自iOS6.0后获取通讯录列表需要询问用户,经过用户同意后才可以获取通讯录用户列表。而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函数转变为ABAddressBookCreateWithOptions函数。下面代码是兼容之前版本的获取通讯录用户列表方法。



ABAddressBookRef addressBook = nil;

if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0) 
{
addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

//等待同意后向下执行

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)

{

dispatch_semaphore_signal(sema);

});

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

dispatch_release(sema);
}
else
{
addressBook = ABAddressBookCreate();
}

NSArray *personArray = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

目前仅知道这些变化,往后再陆续补充完整。

2012年11月18日 星期日

cocopod install


如果裝 gem install cocoapods  沒反應

可能是你的 gem 太舊了

升級 gem

  508  gem -v
  510  sudo gem update --system



  513  sudo gem install cocoapods

CocoaPod 加入自己的 spec資料庫



https://github.com/CocoaPods/CocoaPods/wiki/Sharing-pod-specifications-with-yourself-and-the-world



指令

$ pod repo add my-spec-repo http://github.com/my-account/spec-repo.git


記得 裡面的 檔案結構要為  /xxxxxx/0.0.1/xxxxxx.podspe
https://github.com/CocoaPods/CocoaPods/wiki/Working-with-repositories

不然在執行 pod repo lint my-spec-repo

會報錯


另外  my-spec-repo 會加入到  /Users/willsborKang/.cocoapods/my-spec-repo


之後用  pod search xxxxxx

就可以看到類似....


-> AFDownloadRequestOperation (0.0.1)
   暫時拿別人的來實驗.
   - Homepage: https://github.com/steipete/AFDownloadRequestOperation
   - Source:   https://github.com/steipete/AFDownloadRequestOperation.git
   - Versions: 0.0.1 [myspecrepo repo]

這樣的內容

- Versions: 0.0.1 [myspecrepo repo]    就不會是 [master repo]


======== 我想應該是這樣用

https://github.com/CocoaPods/CocoaPods/wiki/Creating-and-maintaining-a-pod

先在自己的專案下  ex: xxxlib 下建立  一個  xxxlib.podspe

$ pod spec create xxxlib

接著編輯這個podsec


編輯後!!!


$ pod spec lint --local

$ git add -A && git commit -m "Release 0.0.1."
$ git tag '0.0.1'
$ git push --tags


pod spec lint --local  只是先檢查格式對不對

接著commit 到git

然後加上tag

然後push到git server上


接著


$ pod push myspec

如果之前 有加入 pod repo add  myspec xxxxx.git

那這裡就會自動更新 xxxxx.git   server

然後接著 在重新載入到 seach list中

所以上面結束後再執行 pod search xxxlib

就可以看到他在 [myspec repo]  中了











2012年11月17日 星期六

Cocoapods library管理套件的引入


說來慚愧

寫了很久的程式,卻還沒正式開始寫 Unit Test 跟 版本控制 ,有時候真的覺得自己以前玩太兇,

不管,反正有總比沒有開始做好!

今天目標:


第三方的版本控制 + Xcode workspace

workspace 我之前都不是很清楚應該要拿這個幹嘛的

新開一個專案幾乎都是將原始碼啦進去

我自己也知道這樣很呆,而且在版本控制上會有很大的問題

之前又一直被當低階勞工....

真的應該要多了解一下手上的工具才是 orz
http://erlangprogram.com/use-xcode4-workspace


git + cocoapods
http://iiiyu.com/blog/2012/10/26/learning-ios-nontes-fourteen/
http://tw.polydice.com/2012/07/04/cocoapods/
http://josephjiang.com/entry.php?id=342
http://www.cnblogs.com/dragonstreak_1/archive/2012/10/19/2730979.html



如果用到自己的 可能需要這樣做


http://ishalou.com/blog/2012/10/16/how-to-create-a-cocoapods-spec-file/


http://cocoapods.org/


pod 的 dependency


Besides no version, or a specific one, it is also possible to use operators:
> 0.1 Any version higher than 0.1
>= 0.1 Version 0.1 and any higher version
< 0.1 Any version lower than 0.1
<= 0.1 Version 0.1 and any lower version
~> 0.1.2 Version 0.1.2 and the versions upto 0.2, not including 0.2


可能建立起來後 要讓 Jenkins 也能用....


http://tulusha.blogspot.tw/2012/04/jenkins-setup-for-building-xcode.html


先開始實作吧 之後再看看有什麼要記錄的


====== 2012/11/19 =========

Jenkins 上面


1. 因為使用 Cocoapod 所以前面加一個 shell

#!/bin/sh

pod install --no-color


2. 因為變成了 workspace 所以在 Xcode的套件上 需要多寫入 xxxx.xcworkspace

Xcode Schema File = "專案名稱" ex: HandWriting

Xcode Workspace File = xxxx.xcworkspace




Build output directory = ${WORKSPACE}/build (這個好像因為使用 workspace 所以如果不設定 不曉得他build 到哪裡去了orz)

所以對應到的 Archive 也要改一下



另外





也要記得溝 這樣好像才找的到 ....

3. 如果像是 facebook framework

後來也是直接改用 CocoaPods 來引入


因為 如果直接用framework 會讓 Jenkins 的相對路徑跑掉 因為在不同的電腦上


所以為了避免這個麻煩 就直接用 src來建立


現在大致上還有兩個問題:

1. 像是 facebook framework 這樣要怎樣在 jenkins 上重新指定位置?!


2. 像是coredata 產生的 resourcefile 要如何寫進 Cocopad中,讓他在建構的時候產生 並且引入到主要的project中







2012年11月15日 星期四

Jenkins - android + ant + iOS + Xcode

經過一陣的嘗試

Android 和 iOS的部份終於算是搞定大半了



iOS 在Build 的部份設定還算簡單

不過還沒有想過引用library的對應關係要怎樣設定  (因為我通常都是直接啦過去 這項好像很不好 orz)

不過最後 OTA的部份可能需要等  公司帳號申請下來再來做打算



Android 在build 的部份就花了一點時間搜尋

因為 Android在 Local端是用 Eclipse 來開發的

   本身沒有直接產生 在Jenkins + ant 上面要用的build.xml

所以要利用  (ref - android)

./android update project  -n ${JOB_NAME} -p ${WORKSPACE}

-n 會影響到產生的apk的名稱
-p 則是專案所在的資料夾

執行完後 就會產生一個build.xml

不過 可能有時會產生 叫你要輸入  --target  的選項

1. 首先要先檢查是否在Jenkins ref 到的 android SDK是否有 install 對應的api level

通常是上面的問題 因為沒有對應的api level 他會幫你檢查然後報錯

不過不要自己設定 --target,因為這是local 端已經寫好的 設定太多到時候其他專案重複利用性就會比較低了

接著是 如果這個android的專案有用到其他專案的jar

那 server 首先也要有對應的jar的專案

然後在 ant 的
Properties
設定中 加入


sdk.dir=/Users/Shared/Jenkins/android-sdk-macosx
android.library.reference.1=../libfacebook-android/
android.library.reference.2=../easyclass-android/

....


這部份其實可以在  專案資料夾中的 project.properties 看到

不過因為local端的對應位置通常跟 server不同 所以可能需要重新設定對應位置

另外 android.library.reference.n  的規則  可以參閱(ref - android)


apk 的發佈也等到 網路比較快 再想想看

初期可能先用S3看看








2012年11月12日 星期一

Jenkins git ssh

之前Jenkins 我一直搞不定 git by ssh

後來終於知道大概是什麼原因了

1. Jenkins 是用Jenkins的權限

    所以簡單來說 我製作一個 Jenkins的帳號  然後產生 rsa

2.  因為 Jenkins 用ssh時  不能還要輸入密碼

    因為之前不知道 ssh-add 的這個指令

    所以只要將 rsa 加入 ssh中  只要先連過一次,之後就不用打密碼了 .... 應該是之後都不用吧orz



參考下面資料


https://confluence.atlassian.com/pages/viewpage.action?pageId=270827678#SetupSSHforGitandMercurialonMacOSX/Linux-enablessh

Step 4. Start the ssh-agent and load your keys

Users who work in OSX 10.6.8 or later have the option of skipping this step.  Under OSX, the system asks for your connection parameters the first time you try to establish a connection.  It also automatically starts the ssh-agent for you at this time.
Open a terminal window and enter the ps -e | grep [s]sh-agent command to see if the agent is running:
myhost:~ manthony$ ps -e  | grep [s]sh-agent
 9060 ??         0:00.28 /usr/bin/ssh-agent -l
If the agent isn't running, start it manually with the following command:
myhost:~ manthony$ ssh-agent /bin/bash
Load your new identity into the ssh-agent management program using the ssh-add command.
$ ssh-add ~/.ssh/id_rsa
Enter passphrase for /Users/manthony/.ssh/id_rsa: 
Identity added: /Users/manthony/.ssh/id_rsa (/Users/manthony/.ssh/id_rsa)
myhost:~ manthony$ 
Use the ssh-add command to list the keys that the agent is managing.
$ ssh-add -l
2048 7a:9c:b2:9c:8e:4e:f4:af:de:70:77:b9:52:fd:44:97 /Users/manthony/.ssh/id_rsa (RSA)

應該又是前輩!

about git

http://blog.tenyi.com/2011/05/git-http-server-for-windows-and-unixgit.html

http://www.cnblogs.com/tinyfish/archive/2011/01/17/1909463.html

http://phardera.blogspot.tw/2012/09/git-apache-windows-xp.html



http://jacksctsai.blogspot.tw/2012/03/nodejs.html



這個似乎比 github 適合我們現在的狀況
https://bitbucket.org/account/signup/?plan=5_users

因為他是 private  但是我們的人數正好小於 5 人!


這個裡面似乎有很多東西可以哇
以下這篇是架 git just using ssh
http://eeepage.info/git-server-ssh/

2012年11月9日 星期五

音量控制鈕 Volume button

http://fredandrandall.com/blog/2011/11/18/taking-control-of-the-volume-buttons-on-ios-like-camera/

2012年11月6日 星期二

iOS private framework

https://github.com/kennytm/iphone-private-frameworks

Sublime Text 2 使用技巧 轉


似乎是重新整理code的軟體@@?!


http://www.keakon.net/2012/09/17/SublimeText2%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7


完敗 ....orz


https://github.com/tonyarnold/Xcode-4-Uncrustify-Automator-Services

WWDC 2012 Note 轉

http://rocry.com/WWDC/2012/08/22/wwdc2012-notes/


這個大陸人整理的真好  orz

偷看   踩在別人的肩膀上!


http://ke.indiebros.com/2012/06/21/the_new_objc_syntax/



Collection Subscription

LLVM 4.0之前:
1 [NSArray arrayWithObjects:a, b, c, nil]
2 [array objectAtIndex:i]
3 [NSDictionary dictionaryWithObjectsAndKeys:v1, k1, v2, k2, nil]
4 [dictionary valueForKey:k]
LLVM 4.0之后:
1 @[a,b,c]     //这里没有nil
2 array[i]
3 @{k1: v1, k2: v2}     //这里没有nil
4 dictionary[k]