-->

Neater

Be A Warrior, Not A Worrier

用Ruby写Alfred2的Workflow

Mac下的大杀器Alfred2用了好久,Workflow也收集了不少,那为什么不自己写一个呢?当添加一个Workflow时发现,竟然支持这么多的语言,那就用我的最爱Ruby开工吧!

view frame

第一次就拿ASCII码转换练练手吧,可以将十进制ASCII码转换成字符

还可以将16进制ASCII转换成字符

或者把字符转换成ASCII码

为MBProgressHUD添加取消功能

MBProgressHUD是一个显示HUD窗口的第三方类库,用于在执行一些后台任务时,在程序中显示一个表示进度的loading视图和两个可选的文本提示的HUD窗口。

在现实的需求中,可能存在这种情况:比如一个网络操作,在发送请求等待响应的过程中,我们会显示一个HUD窗口以显示一个loading框。但如果我们想在等待响应的过程中,在当前视图中取消这个网络请求,就没有相应的处理方式,MBProgressHUD没有为我们提供这样的交互操作。

简单看了下MBProgressHUD的源码,发现使用了NSOperationQueue来调度任务,便有了下面代码。

1
2
3
4
5
6
7
8
9
10
- requestData
{
   self.manager = [AFHTTPRequestOperationManager manager];
  UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cancelRequest)];
}

- (void)cancelRequest
{
    [self.manager.operationQueue cancelAllOperations];
}

Android实用实践Part1: 架构

本文是这一系列的开篇,主要涉及一些基础环境设置,目的是能开发出及扩展、及维护和易测试的项目,而本系列将会涵盖一些模式和库,它们会或多或少改善让Android开发者的体验。

场景

本篇使用的Android项目救命,是个电影类别的原型,可以标记是否已经观看,影片的信息可以通过themoviedb提供的API获得,Apiary上有相关的文档,这个工程基于MVP模式,遵循了Material Design,如转场、结构、动画、动画等。

Github上有示例代码,并配有视频。

架构:

iOS中的Hit-Testing

Hit-Testing决定了一个触控点是否和屏幕上的视图相关,iOS使用Hit-testing找到最前端的并且该视图能够接收用户触碰产生的事件。这背后的实现采用了reverse pre-order depth-first遍历算法。

解释Hit-Testing原理之前,先来看看它产生的时机,下面的示意图说明了一次touch从手指触碰屏幕到离开的过程

iOS开发最佳实践

和软件一样,这篇文章离不开大家的贡献,哪怕打开一个Issue或者发一个PR。

如果对Android感兴趣,请看这里 Android开发最佳实践

起因

遗憾地是,iOS开发的门槛挺高的,Swift和Objective-C都没有在iOS/Mac以外的系统广泛使用,而且有自己的命名方式,想让代码跑在苹果的设备上并不容易(译者注:各种编译和开发环境问题),不论你刚接触Cocoa还是对iOS开发最佳实践感兴趣,都能在这里找到答案。下面列出的只是一些建议,如果你有更好的实践可以进行相应的替换。

开始

Xcode

Xcode是绝大多数iOS开发者选择的IDE,并且是苹果官方唯一支持的。当然也有其它的,AppCode可以说其中最著名的,不过如果你还不是一个iOS开发的老手,还是使用Xcode吧,不管怎么样,它在可用性方面还是不错的。

可以在Mac App Store下载最新的SDK和模拟器,在Preferences > Downloads中可以下载更多的文档。

项目设置

刚开始开发iOS项目有个很常见的问题,纯代码?Storybard?还是XIB,用哪一个来开发UI,Both are known to occasionally result in working software。但是,还要从下面几个方面来考虑:

纯代码?

  • Xcode5中,通用型App使用不同的Storyboard区分iPhone和iPad,这导致了许多不必要的重复,Xcode6引入了Size Classes来解决这个问题。
  • Xcode5中,Storyboard不支持自定义字体和UI元素, but will have a generic appearance instead,Xcode6再次解决了它。
  • Storyboard使用了复杂的XML,在版本控制中,更容易产生冲突。

Storyboards?

  • or the less technically inclined, Storyboards在操作方式上做的最好,比如,直接修改颜色或者布局约束,当然这需要一些时间来学习。

Ignores

把项目加入版本控制的时候,最好也加入.gitignore文件,这样不会把不需要的文件(用户自己的配置和临时文件等)加入。幸运地是,GitHub已经为我们提供了Objective-CSwift的版本(译者注:还有个好用的网站,gitignore.io)

全栈开发者的潮起潮落

貌似今天的技术都迷恋全栈的开发者。全栈可能在Web2.0时代是可能的,但新一代的创业公司的涌现打破了许多限制。从机器智能预测推计算数据分析移动/可穿戴等等,全栈变得几乎不可能了。

上世纪70年代末至80年代初,还是孩子的我便开始为早期移动端和网站编程,那时独立开发一个软件是很普遍的,程序员和硬件之间也没有很多的层。在8位处理器和有限的内存环境下,程序员使用汇编语言尽可能地提升运行的性能和空间。

80年代末至90年代初,随着C/S模型的到来,很快软件开发演变成了一种团队合作,而90年代末至新世纪初的互联网浪潮则加速了这一进程。新进的技术进一步提高了复杂度,管理一个商业网站需要具备多种技能(比如前端、数据库、应用服务器等)的专业人员精通网络设备的操作、路由器和负载均衡原理、Java虚拟机调优、各种数据库的索引机制。

00年代中期开始,任何项目的开发成本都变的非常高,从简单的网站到新一代SaaS服务,这直接增加了开发中各个层之间的沟通成本甚至还会造成沟通障碍,项目中的层数也增加了不少,直接增加了部署的难度。 正如Marc Andreessen针对最近tweet的烧钱风波(译者猜测是狂招人吧)指出:开发人员的增加极大增加了沟通成本,只会导致效率的降低。

与之相反,新一代Web2.0技术变得日益简单和无缝。使用J2EE及Oracle的程序员切换到了更加一体化的LAMP(Linux, Apache, MySQL, PHP/Python/Perl)。新的语言及其框架(Django and Ruby on Rails)在网站和数据库之间封装相应的层来完成自动化。前端框架(jQuery)提供抽象层使开发者不用关心具体的浏览器。云服务(Amazon Web Services)简化部署并提供一致的网络。

00年代后期,许多程序员都能独自交付一个消费类或SaaS网站,包括动态网络客户端,以及负责商业逻辑的服务端,数据库的开发、布署以及运维。这新一代全栈开发者可以完全胜任需要过去一个团队才能完成的任务。当新加入的全线开发者为项目开发一个新的功能,将不可避免地涉及项目的各个层,

skill1

如果你要使用上图中的技术来搭建网站,需要找到能够胜任的程序员。不久之后我觉得不切实际,因为这是并不是全栈开发者,下面的才是: skill2

我敢打赌,没人能精通所有这些领域,并开发相应的应用,因为要精通每一个领域及其API都是一个全职工作。

我们正处于复杂技术的变迁中,每个技术层都需要相关专家。开发Android&iOS App需要理解各自平台的特性。使用Amazon的云服务运行一个应用,需要熟悉它的各种服务,才能应付各种事故。甚至前端技能的CSS都到了CSS4,JSON&JavaScript也出现了MVC框架,Angular.js & Backbone.js.

在这勇敢的新世界,一种人成为了关键,他除了精通至少一个层,还要能连接其余的层,并能和各层的专家合作开发新的功能并交付。换言之,他能够连接各个层以及设计整体的架构,这样的人很可能是一个或几个层的专家,相比全栈开发者,我们更需要全栈集成者。

安息吧,全栈开发者,我们应该欢迎全栈集成者,除了某些特殊领域需要具备高超技术的工程师外,软件使世界变得更加美好,其中自然少不了你们。

译自: The Rise And Fall Of The Full Stack Developer

Git Tips

取消一次 git merge,比方说刚才执行了 git merge dev,发现各种崩溃,一大堆 conflict,想取消掉,那么就执行

1
git reset --merge dev 

显示某个作者的提交

1
git log --name-status --author="[The Author's Name]" 

从仓库取出file覆盖当前分支

1
git checkout branch|tag|commit -- file_name

Branch

查看各个分支最后一个提交对象的信息

1
git branch -v

查看已经合并到当前分支的分支

1
git branch --merge

查看未合并到当前分支的分支

1
git branch --no-merge

基于dev新建test分支,并切换

1
git checkout -b test dev

Others

停止追逐现在已经追踪的文件

1
git rm --cached

返回一个简单版的git status,为默认git status来减少噪音。

1
git status -s

显示提交记录的参与者列表。和GitHub的参与者列表相同。

1
git shortlog -sn

Revert

  1. 提交过版本库,但未提交至暂存区的文件(未执行 git add),此类文件的状态为 Changes not staged for commit,撤销方法:

     git checkout .
    
  2. 新建的文件和目录,且从未提交至版本库,此类文件的状态为 Untracked files ,撤销方法如下:

     git clean -fd .
    
  3. 已提交至暂存区的文件,此类文件的状态为 Changes to be committed,执行之后文件将会回到以上的 1 或者 2 状态

     git reset .
    

从暂存区去除文件覆盖工作区

git checkout -- .

读取指定文件合并到当前分支

git checkout screencast -- file1 file2 etc.

与 git add -p 对应

git checkout -p

ReactiveCocoa and Swift

Swift可以和Objective-C相互调用,所以,在用Swift编写的App中,可以直接使用Reactivecocoa。

尽管如此,

Signals in Swift

通过桥接,ReactiveCocoa的API从Objective-C的块过渡到了Swift的闭包,来看一个例子,下面的Objective-C代码subscribe了UITextfield的rac_textSignal,用来查看当前的length。

1
2
3
4
[self.searchTextField.rac_textSignal subscribeNext:^(id x) {
  NSString *text = (NSString *)x;
  NSLog(text);
}];

当在这个UITextfield中依次输入0 1 2 3 4 5时,Console中显示

1
2
3
4
5
6
0
1
2
3
4
5

当然了,为了避免显示转换,可以把上面的Block签名中的参数类型,从id改为NSString:

1
2
3
[self.searchTextField.rac_textSignal subscribeNext:^(NSString *text) {
  NSLog(text);
}];

与之对应的Swift代码如下:

1
2
3
4
5
6
searchTextField.rac_textSignal().subscribeNext {
  (next:AnyObject!) -> () in
  if let text = next as? String {
    println(countElements(text))
  }
}

不幸的是,当Swift和Objective-C进行调用的时候,会经常用到as操作符,从而变得更复杂了,我们不能进行显示转换,Swift生硬地插入了必须的类型为(AnyObject!) -> ()的函数。

也可以使用if-let条件语句进行简化,因为AnyObject在当前情况下可以视为字符串。

1
2
3
4
5
searchTextField.rac_textSignal().subscribeNext {
  (next:AnyObject!) -> () in
  let text = next as String
  println(countElements(text))
}

但是,这仍然还是要比Objective-C的版本复杂。 还好有解决这个问题的方案!针对RACSignal进行扩展,把传入函数参数类型进行必须的转换:

1
2
3
4
5
6
7
8
9
extension RACSignal {
  func subscribeNextAs<T>(nextClosure:(T) -> ()) -> () {
    self.subscribeNext {
      (next: AnyObject!) -> () in
      let nextAsT = next as T
      nextClosure(nextAsT)
    }
  }
}

上面的代码使用泛型进行类型转换,参数T的类型通过实际传入的参数进行推断,这引出了一些有趣的语法

1
2
3
4
searchTextField.rac_textSignal().subscribeNextAs {
  (text:String) -> () in
  println(countElements(text))
}

100个iOS开发者需要关注的资源

iOS App的市场无疑获得了极大的增长,当然少不了平台流行的功劳。下面的的资源,对App开发感兴趣的人是很有帮助的。

无论是在App Store推广你的App,还是设计一款漂亮的App,这些书、工具、社区绝对能帮助你。这100多个在线服务、社区、工具,帮助开发者更好的构思一款App并实现它,你所要做的就是好好使用它们。

在线服务

Service

  1. Iubenda – Mobile app privacy policy
  2. Content -Content management system for native iOS apps
  3. Unbabel – App Localization
  4. Switch -Toggle your app features off and on in real-time
  5. Heatmaps – iOS heatmap
  6. Bitbucket – Private code repositories
  7. Media Toolkit – Monitors mentions of your app
  8. Alau.me – Like bit.ly for apps
  9. Ap Salar – Data driven mobile ad platform
  10. Google – Mobile backend

社区

Communities

  1. iOS Developers Group – iOS Google+ community
  2. iOS Meetup Groups – Get together with like-minded people
  3. iOS Development Quora – iOS Development Quora group
  4. iOS Stackoverflow – iOS Stackoverflow group
  5. iPhone Developer Forum – iOS Dev Forums
  6. iOS Programming – iOS Reddit group
  7. Cocoa Lit – List of Cocoa tutorials
  8. NS Screencast – iOS development screencasts
  9. iOS Developer Tips – Tips and tutorials for iOS Developers
  10. Clarity.fm – Call an expert for iOS help

译自 100 Great Resources for iOS Developers

FLEX!iOS调试利器

FLEX (Flipboard Explorer)是一系列集成在APP内部的用于iOS调试的工具集,以工具栏的形式显示在应用中,通过它,可以查看并修改几乎所有的APP运行状态。

dfd

强大的调试能力

  • 查看、修改View的层次关系。
  • 查看对象的属性和实例变量。
  • 动态修改属性和实例变量。
  • 动态调用实例和类方法。
  • 动态访问堆上的对象。
  • 访问APP的沙盒。
  • 除jAPP的所有类外,还能访问已链接的系统框架,包括私有的。
  • 快速访问一些常用的对象,比如[UIApplication sharedApplication]、App Delegate、Root View Controller等。
  • 动态查看、修改NSUserDefaults存储的值。

和其它调试工具不同,FLEX完全运行在你的APP中,所以不需要连接到LLDB/Xcode或者远程调试的服务端,在模拟器和真机上都运行的很好。