第一次产品小结:不及格
第一次自己作为产品负责人带产品,自评不及格。总结一下,以后这样的机会还会很多,积累经验争取下次做的更好。
- 开发进度太慢。原本计划一周时间出原型,但是拖了两个星期才发了第一个测试版本,delay 太多了。自己负责的开发部分拖累了整个项目进展,这一点必须反思。
- 进度慢的一个原因是部分模块沿用之前项目的东西,花了很多时间去理解梳理然后添加到现在项目,但是由于两个项目架构等有很多不同,复用的成本太大。自己作为项目负责人,选型时候没有考虑清楚,引入后影响项目进度,却没有及时的拿出修正方案。教训一:不通用的模块复用的成本远远大于重写一份,切不可为了一时的快而忽视其他问题。
- 另一个原因是在项目基本成型的时候,由于数据库一个设计缺陷,虽不影响当前使用,但很不利于以后的产品拓展,就重构了一下。这个相比上面虽然有了解决方案,但是延期是事实。究其原因还是在开发前期没有很好的考虑清楚,只解决了第一需求就立马开工,后期造成返工。教训二:产品设计,尤其是开发设计,架构方面要考虑清楚,要有一定的可扩展性,避免以后返工。
- 作为产品负责人,忽略了开发以外的很多事情。比如设计方面,只是和设计师确定了基本界面和交互流程,然后一股脑的扎进开发去,加上开发跑偏,花在设计上的心思就更少了。还好旁边有人提醒着,设计方面这次没有拖累项目进展,但由于和设计师沟通交流太少,一些产品概念没有准确的传递给设计师,造成一些细节上不够完美。教训三:作为产品负责人,要对整个产品线全部部分掌握到把控到,并且准确的传递给相关人员。
- 作为产品负责人,要 主动 和项目中的其他人员多沟通,一方面把产品传递给其他人,更重要的是要收集汇总其他人员对产品的概念和想法,然后迭代修正不完善的地方,再一个可以及时了解其他人的进度和遇到的问题,以便整体安排。
- 这次产品调研阶段确定了不少功能点要做,但是没有完全定型 当前版本 要做的点,这就造成一方面有东西没有做完,产品不能成型,另一方面却花了不少时间做了一些可以后续再增强的东西,造成时间的浪费。教训四:要控制产品功能的阶段性,必要时可以砍掉一些功能点来保证当前版本上线,然后再快速迭代产品。
- 对开发分工和实际进度掌握不好。不是分工后就完全分工不管了,如果有人负责的部分提前完工,可以再对未完成的部分分工一下,虽然可能会增加一些人的负担然后引发其他问题,但是从整个产品进展来看,这样做无可厚非。
- 技术人做产品会有惯性思维,考虑问题过多从开发角度思考,这样的结果一是产品讨论时过于关注开发实现,产品比较僵硬;二是后续比较多的心思都花在了开发上,整体把握不足,引发上面两个问题。教训五:做产品的时候要跳出开发这个圈圈,这样才能碰撞出更多点子;要平衡好产品和开发。
现在回过头来想想,自己这次产品做的真不咋样,好好反思一下,希望下次能有更好的表现。
题外话。
- 过于追求完美是做产品的大忌。
- 不要因为自己的错误影响别人的利益。
- 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 可以很方便的查看界面元素排版布局。
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
Setup Mac Development Environment
- System Software Update.
- Download and install Xcode, or Command Line Tools for Xcode only if you don’t need Xcode.
- Install Homebrew.
- Get back your dotfiles if you have.
Python
- Use
pip
instead ofeasy_install
- Use
pip
to installvirtualenv
andvirtualenvwrapper
# 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.
- Download svn-1.7.2.tar.gz source.
- Run
./autogen.sh
to check the necessary components to build svn. ./configure
thenmake
andsudo 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 来查找。解决方法:
- 更换 SSD,一劳永逸,更能带来编译速度的极大提升。
- 第三方文档搜索工具,比如 Ingredients、AppKiDo,缺点是没法和 Xcode 完美结合,比如 Option+Click 快速查找。
- 修改 Find Options 来减少一些索引,只做 iOS 就没必要选 Mac 的 Doc Sets. 另外 Match Type 选 Prefix 也会快很多。可以参考下面这个 Find Options 设置。
感谢 @jjgod 分享的小技巧。
[self review:2011];
2011
2011 年度个人总结。
工作
一整年的 iOS 开发,相对于去年入门时 Rookie 最大的成长是教训,经验和信心。
有那么一次,客户端测试时候频繁崩溃却毫无头绪,那个上火啊,甚至晚上做梦都在 Debug,有一晚上还真在梦中解决了一个问题。没有教训就没有记忆,这也是为啥后来我偏执的强迫症般的抓内存泄漏找潜在崩溃。经验就是由这么一堆教训堆积出来的,一次次的总结然后下一次避免,这不就是成长么?
如果一年前跟我说我们的竞争对手如此之多,甚至还有上市公司,我绝对没有信心去继续这个项目。不是说我太消极,而是对于这个市场的一无所知。不是都说恐惧源自于无知么。这一年下来,随着技术上的完善,产品的坚持,市场的更加熟悉,我们现在是信心满满的面对每个竞争对手。
本来四季度时想跟进学一下服务端开发,阴差阳错的给错过了,算是今年的一个遗憾吧。来年一定要跟进。
没来得及搞服务端,腾出时间整理了内部 iOS 编码规范和通用库,这个过程正好把前面一年的开发梳理了一下,收获很大。以后要坚持定期的回头梳理。
产品细节上这一年有不少进步,但是整体把控还不行,产品这一块是个长期,坚持。
生活
圣诞节时跟远大萌感慨说老了,平安夜都没有出去 High。其实是平静了,我们会周末窝家里做饭,给爸妈打电话唠叨,我觉得挺好。
今年最高兴的就是在家里需要的时候我和妞妞有能力帮一把,不让爸妈那么累,那么苦,尽管力量还很小。我一直认为家是生活的中心,如果连家里人的生活都无力改善,那你改变世界的理想都是扯淡。
大年初六我和妞妞订婚了。这一年我们有生气,有争吵,但我们比以往更爱对方。两个人在一起不容易,很感谢妞妞对我的理解、支持和包容。
这一年控制着没有继续长胖,不过也没有瘦,身体没有什么大毛病,但明显身体素质比以前差了不少,得加强一下锻炼,向罗胖子学习。
2012
工作
- 加强 iOS 开发,尤其是新技术的学习和整理,比如 ARC。
- 尝试 iPad 开发,这可不是简单的界面放大,整个用户交互都需要重新学习理解。
- 服务端开发,至少是应用级别要跟上,已经落户一步,不能拖太久。
- 继续加强产品能力,尤其是整体把握。
生活
- 完婚。
- 给家里更多的帮助,让爸妈轻松一点。
- 希望今年能有一次旅游,厦门?
最后来张截图
[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,会有系统弹窗提示 “无邮件账户”。