第一次产品小结:不及格

第一次自己作为产品负责人带产品,自评不及格。总结一下,以后这样的机会还会很多,积累经验争取下次做的更好。

  1. 开发进度太慢。原本计划一周时间出原型,但是拖了两个星期才发了第一个测试版本,delay 太多了。自己负责的开发部分拖累了整个项目进展,这一点必须反思。
  2. 进度慢的一个原因是部分模块沿用之前项目的东西,花了很多时间去理解梳理然后添加到现在项目,但是由于两个项目架构等有很多不同,复用的成本太大。自己作为项目负责人,选型时候没有考虑清楚,引入后影响项目进度,却没有及时的拿出修正方案。教训一:不通用的模块复用的成本远远大于重写一份,切不可为了一时的快而忽视其他问题
  3. 另一个原因是在项目基本成型的时候,由于数据库一个设计缺陷,虽不影响当前使用,但很不利于以后的产品拓展,就重构了一下。这个相比上面虽然有了解决方案,但是延期是事实。究其原因还是在开发前期没有很好的考虑清楚,只解决了第一需求就立马开工,后期造成返工。教训二:产品设计,尤其是开发设计,架构方面要考虑清楚,要有一定的可扩展性,避免以后返工
  4. 作为产品负责人,忽略了开发以外的很多事情。比如设计方面,只是和设计师确定了基本界面和交互流程,然后一股脑的扎进开发去,加上开发跑偏,花在设计上的心思就更少了。还好旁边有人提醒着,设计方面这次没有拖累项目进展,但由于和设计师沟通交流太少,一些产品概念没有准确的传递给设计师,造成一些细节上不够完美。教训三:作为产品负责人,要对整个产品线全部部分掌握到把控到,并且准确的传递给相关人员
  5. 作为产品负责人,要 主动 和项目中的其他人员多沟通,一方面把产品传递给其他人,更重要的是要收集汇总其他人员对产品的概念和想法,然后迭代修正不完善的地方,再一个可以及时了解其他人的进度和遇到的问题,以便整体安排。
  6. 这次产品调研阶段确定了不少功能点要做,但是没有完全定型 当前版本 要做的点,这就造成一方面有东西没有做完,产品不能成型,另一方面却花了不少时间做了一些可以后续再增强的东西,造成时间的浪费。教训四:要控制产品功能的阶段性,必要时可以砍掉一些功能点来保证当前版本上线,然后再快速迭代产品
  7. 对开发分工和实际进度掌握不好。不是分工后就完全分工不管了,如果有人负责的部分提前完工,可以再对未完成的部分分工一下,虽然可能会增加一些人的负担然后引发其他问题,但是从整个产品进展来看,这样做无可厚非。
  8. 技术人做产品会有惯性思维,考虑问题过多从开发角度思考,这样的结果一是产品讨论时过于关注开发实现,产品比较僵硬;二是后续比较多的心思都花在了开发上,整体把握不足,引发上面两个问题。教训五:做产品的时候要跳出开发这个圈圈,这样才能碰撞出更多点子;要平衡好产品和开发

现在回过头来想想,自己这次产品做的真不咋样,好好反思一下,希望下次能有更好的表现。


题外话。

  1. 过于追求完美是做产品的大忌。
  2. 不要因为自己的错误影响别人的利益。
  3. Deadlines kill quality。

Grand Central Dispatch Sample

说来惭愧,做 iDev 一年多了,最近才第一次在正式项目中使用 GCD。做个笔记。

Grand Central Dispatch(GCD) 是苹果 iOS 4 推出的任务调度机制,把不同的任务分配给不同的 queue 来处理,非常适合异步任务,支持多核处理器,比 performSelectorInBackground 这种线程调度有更好的处理性能,而且配合 Blocks 使用非常方便。

dispatch_queue_t bgQueue = dispatch_queue_create("im.fann.bgQueue", NULL);
// or dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// or dispatch_queue_t bgQueue = dispatch_get_global_queue(0, 0,); for short

dispatch_async(bgQueue, ^{

    ...// load data from server

    dispatch_async(dispatch_get_main_queue, ^{
        // dispatch_get_main_queue get back to the main queue to update UI. You can only change UI in main queue.
        [rootTableView reloadData];
    });
});

非常棒的 GCD 系列教程:

Happy Birthday to my Blog

四年前的今天写了 Hello World!,希望能一直写下去。

Happy Birthday.

iOS 模拟器界面调试小工具

不知道 Xcode 什么时候添加进来的功能,在模拟器 Debug 菜单下选中 Color Blended Layers 可以很方便的查看界面元素排版布局。

Color Blended Layers

BTW, 现在在模拟器可以直接 Command+S 来截图了。

iOS 5 Settings URL scheme

在 iOS 5+ 可以通过 URL scheme 快速打开【设置】及子项。

Settings                prefs:
About                   prefs:root=General&path=About
Accessibility           prefs:root=General&path=ACCESSIBILITY
Airplane Mode On        prefs:root=AIRPLANE_MODE
Auto-Lock               prefs:root=General&path=AUTOLOCK
Brightness              prefs:root=Brightness
Bluetooth               prefs:root=General&path=Bluetooth
Date & Time             prefs:root=General&path=DATE_AND_TIME
FaceTime                prefs:root=FACETIME
General                 prefs:root=General
Keyboard                prefs:root=General&path=Keyboard
iCloud                  prefs:root=CASTLE
iCloud Storage & Backup prefs:root=CASTLE&path=STORAGE_AND_BACKUP
International           prefs:root=General&path=INTERNATIONAL
Location Services       prefs:root=LOCATION_SERVICES
Music                   prefs:root=MUSIC
Music Equalizer         prefs:root=MUSIC&path=EQ
Music Volume Limit      prefs:root=MUSIC&path=VolumeLimit
Network                 prefs:root=General&path=Network
Nike + iPod             prefs:root=NIKE_PLUS_IPOD
Notes                   prefs:root=NOTES
Notification            prefs:root=NOTIFICATIONS_ID
Phone                   prefs:root=Phone
Photos                  prefs:root=Photos
Profile                 prefs:root=General&path=ManagedConfigurationList
Reset                   prefs:root=General&path=Reset
Safari                  prefs:root=Safari
Siri                    prefs:root=General&path=Assistant
Sounds                  prefs:root=Sounds
Software Update         prefs:root=General&path=SOFTWARE_UPDATE_LINK
Store                   prefs:root=STORE
Twitter                 prefs:root=TWITTER
Usage                   prefs:root=General&path=USAGE
VPN                     prefs:root=General&path=Network/VPN
Wallpaper               prefs:root=Wallpaper
Wi-Fi                   prefs:root=WIFI

via Apple Settings App/Preference Shortcuts

Setup Mac Development Environment

  1. System Software Update.
  2. Download and install Xcode, or Command Line Tools for Xcode only if you don’t need Xcode.
  3. Install Homebrew.
  4. Get back your dotfiles if you have.

Python

  1. Use pip instead of easy_install
  2. Use pip to install virtualenv and virtualenvwrapper
# use easy_install to install pip
sudo easy_install pip
# where pip
/usr/local/bin/pip
# virtualenv
sudo pip install virtualenv
# which virtualenv
/usr/local/bin/virtualenv
# virtualenvwrapper
sudo pip install virtualenvwrapper
# virtualenvwrapper will be installed in /usr/local/bin/virtualenvwrapper.sh
# config virtualenvwrapper
mkdir ~/.virtualenvs
# edit .zshrc and add
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

Ruby

Install RVM

# add to .zshrc
[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm
# install ruby by rvm
rvm install 1.9.2 && rvm use 1.9.2
rvm rubygems latest

Compile and install SVN 1.7.2 on Mac

Just a note for myself.

  1. Download svn-1.7.2.tar.gz source.
  2. Run ./autogen.sh to check the necessary components to build svn.
  3. ./configure then make and sudo make install.

All commands:

./autogen.sh
./configure --disable-debug --with-ssl --with-zlib=/usr --with-sqlite=/usr --disable-neon-version-check --disable-mod-activation --without-apache-libexecdir --without-berkeley-db --with-neon=/usr/local/Cellar/neon/0.29.6/
make
sudo make install

加速 Xcode 文档搜索

Xcode 的文档搜索速度实在是不给力,因为 Xcode 是实时的索引所有 Doc Sets 来查找。解决方法:

  1. 更换 SSD,一劳永逸,更能带来编译速度的极大提升。
  2. 第三方文档搜索工具,比如 Ingredients、AppKiDo,缺点是没法和 Xcode 完美结合,比如 Option+Click 快速查找。
  3. 修改 Find Options 来减少一些索引,只做 iOS 就没必要选 Mac 的 Doc Sets. 另外 Match Type 选 Prefix 也会快很多。可以参考下面这个 Find Options 设置。

speedup Xcode doc search

感谢 @jjgod 分享的小技巧。

[self review:2011];

2011

2011 年度个人总结。

工作

一整年的 iOS 开发,相对于去年入门时 Rookie 最大的成长是教训,经验和信心。

有那么一次,客户端测试时候频繁崩溃却毫无头绪,那个上火啊,甚至晚上做梦都在 Debug,有一晚上还真在梦中解决了一个问题。没有教训就没有记忆,这也是为啥后来我偏执的强迫症般的抓内存泄漏找潜在崩溃。经验就是由这么一堆教训堆积出来的,一次次的总结然后下一次避免,这不就是成长么?

如果一年前跟我说我们的竞争对手如此之多,甚至还有上市公司,我绝对没有信心去继续这个项目。不是说我太消极,而是对于这个市场的一无所知。不是都说恐惧源自于无知么。这一年下来,随着技术上的完善,产品的坚持,市场的更加熟悉,我们现在是信心满满的面对每个竞争对手。

本来四季度时想跟进学一下服务端开发,阴差阳错的给错过了,算是今年的一个遗憾吧。来年一定要跟进。

没来得及搞服务端,腾出时间整理了内部 iOS 编码规范和通用库,这个过程正好把前面一年的开发梳理了一下,收获很大。以后要坚持定期的回头梳理。

产品细节上这一年有不少进步,但是整体把控还不行,产品这一块是个长期,坚持。

生活

圣诞节时跟远大萌感慨说老了,平安夜都没有出去 High。其实是平静了,我们会周末窝家里做饭,给爸妈打电话唠叨,我觉得挺好。

今年最高兴的就是在家里需要的时候我和妞妞有能力帮一把,不让爸妈那么累,那么苦,尽管力量还很小。我一直认为家是生活的中心,如果连家里人的生活都无力改善,那你改变世界的理想都是扯淡。

大年初六我和妞妞订婚了。这一年我们有生气,有争吵,但我们比以往更爱对方。两个人在一起不容易,很感谢妞妞对我的理解、支持和包容。

这一年控制着没有继续长胖,不过也没有瘦,身体没有什么大毛病,但明显身体素质比以前差了不少,得加强一下锻炼,向罗胖子学习。


2012

工作

  1. 加强 iOS 开发,尤其是新技术的学习和整理,比如 ARC。
  2. 尝试 iPad 开发,这可不是简单的界面放大,整个用户交互都需要重新学习理解。
  3. 服务端开发,至少是应用级别要跟上,已经落户一步,不能拖太久。
  4. 继续加强产品能力,尤其是整体把握。

生活

  1. 完婚。
  2. 给家里更多的帮助,让爸妈轻松一点。
  3. 希望今年能有一次旅游,厦门?

最后来张截图

2011

[MFMailComposeViewController canSendMail] issue

发现 MFMailComposeViewController 一个挺奇怪的问题,代码一:

if ([MFMailComposeViewController canSendMail]) {
    MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
    [mailComposer setSubject:@"Mail"];
    //...
    [self presentModalViewController:mailComposer animated:YES];
    [mailComposer release];
}

如果设备没有设置 Mail,那么该操作不会有任何反应。不会有弹窗出现。

代码二:

MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
if (![MFMailComposeViewController canSendMail]) {
    return;
}
//...

代码二这种情况下如果没有设置 Mail,会有系统弹窗提示 “无邮件账户”。