分类
stuff

密码保护:立春

此内容受密码保护。如需查阅,请在下列字段中输入您的密码。

分类
dev

Xcode 文档与注释

最近在着手把公司项目的数据操作算法与界面控制分离开来,准备了一个数据操作的动态库用来写这部分代码,考虑到代码的使用对象,为本公司里,应用的编写人员,所以文档的需求就变得更为迫切。

大致考虑了一下,文档需要与方法编写同时产生。

应用

实际应用,就是比较简单的策略:

编写代码时,使用规范的注释。完成功能后,生成一遍注释,更新到网上。

选择

  • headerdoc2html

headerdoc2html为自带文档生成工具,命令即可操作,具体参数命令会提示。

  • doxygen

官方链接 doxygen

doxygen的非常不错,也有应用程序方便的生成文档,还有很多不同类的语言支持。

文档相关功能也挺不错的,目录结构,搜索,还有关系图表。

也有配置文件,方便下一次文档更新的生成。

目前暂定该方案。

Author

骆昱(Luo Yu), indie.luo@gmail.com

Monday, January 16, 2017

分类
dev

基于Web技术的桌面应用开发

前因

因为工作的原因,在思考如何选择下一代应用开发技术,应对当前问题。

基于Web相关技术进行跨平台程序开发其实早在移动平台刚刚大红大紫的年代就被炒得很热门了,但是目前由于各种原因(诸如交互体验,以及与其他技术混合等等),我在移动平台应用开发上,首选的仍然会是原生开发的方式。

不过这种方式,放在桌面应用上却是很好的。桌面级应用,有着更好的系统资源,更少的限制条件。

注意事项

Web技术的桌面端应用明显会在电源优化上存在劣势,所以如果应用需要长时间操作,跨越几次系统休眠/睡眠,使用场景有电池续航状态等,还是更应该考虑原生语言开发.

进行

目前在研究的是Electron框架: 官网

Github内部据称使用多年的Atom编辑器,即是使用electron框架编写的。

Author

骆昱(Luo Yu)

2016-12-28

分类
stuff

九月十日先生 App上线啦!

App Store 链接:



⬇️ 长这个样子 ⬇️

分类
dev

Module化的 iOS应用开发

因工作需要,开始希望移动应用开发能走模块/组件式的过程,来提高功能的复用性,减少开发的时间,从而满足快速的产品输出需求。

需求的来源源自公司的新项目方向通常是与已有的项目存在部分类似的功能,又有自己独特的模块。

在此基础下,将功能尽量独立出来,做到不同项目导入+配置即可使用,除了减少开发、测试的工作,也可提高该功能的可维护性(修改一次代码,可以同时更新多个引用此功能的项目)。

难点在于模块式的iOS应用开发。

首先是解耦功能。

实际情况1

考虑到网络层一般已有AFNetworking/Alamofire这样的库,网络层通常是对应Server RESTAPI进行配合,做初步解析,区分API Error与Success,以便每个数据请求处理结果。

对于某些特定的情况,例如没有对OSS文件服务器接口进行包装的Server,文件上传的操作也是在App内做的情况下,这些操作也应该归纳到网络层的范围内。

这样下来,如果在Server Domain,API前缀,OSS鉴权信息等可配置的情况下,可以将该组件+网络库(如AFNetworking)独立出来,形成一个模块。

实际情况2

用户登录

包含用户的权限判定,与登录界面显示的触发;登录界面UI与输入交互;登录操作的网络请求,成功失败的处理等。

权限判断与界面触发都与其他界面里用户的操作相关联,但可行的是,判断本身都是与固有数据的操作,是外部对模块内的单向调用。

登录界面UI,无法确定,同一家公司的话,可能有一定的复用性,具体情况待定。

网络请求可以暴露出组件,或是可配置的请求地址,待定。

可见登录,是一个有部分独立性的模块。

实际情况3

注册

注册UI,无法确定,不同项目有不同的注册所需字段的需求;
注册步骤,无法确定,不同项目,注册的流程都可能不一样,有的追求简单快速,有的则有许些必要的信息需要录入并验证。

注册不应该做成模块,可复用性也很低。

模块与项目引用的解决方案

首先,应该考虑的是Git与Git Submodule,似乎生来就是为项目模块化设定的。

好处有很多,依赖关系很明确,所见即所得,如何将模块添加到工程都是开发人员自己决定的。

而对于工程本身来说,其实还是一个整体。

编译输出全在一个二进制文件里。

其次,使用私有的Cocoapods进行配置管理。

思路大致如下:

分类
stuff

Terminal 终端

我用Mac终端 只用iTerm2。

完。

哪有那么简单。

关于终端的配置,首先,系统默认的Terminal其实也是一个很不错的选择,

它跨越不同配置的电脑环境,任一台Mac,都能有该终端,都可能有默认配置,

所以熟悉这,也是很有很有必要的。

然而它默认是Bash,虽然早些年(Tiger)感觉很先进的选择,但是现在我感觉更倾向于Zsh。

chsh -s $(which zsh)设置Zsh为默认,需要输入一次密码。

另外一个收关注度很高的oh-my-zsh,Zsh用户不容错过啊!

它的官网 Oh-my-zsh

分类
dev

iOS中 OCR光学识别的运用

在一些特定场景下我们需要利用iPhone(or any iOS devices)的摄像头来进行光学识别(OCR-Optical Character Recognition),本文即是对此方向的研究。

版权所有,如转载请先联系indie.luo@gmail.com。


一些轮子:

  • TesseractOCR

Tesseract OCR iOS | 开源的OCR框架,在其GitHub页面上可发现仍然持续更新中。
它是Tesseract框架的一个iOS实现。

关于当前(Jul 19, 2016)TesseractOCR-iOS的一些注意事项:
使用的Tesseract库版本为 3.03-rc1。所以在Github上找到的3.04语言训练文件不能用会报错。
实测可以使用旧版3.02版本的语言训练文件。(同样的问题出现在chi_sim, jp等语言上)。

Github的issues里作者有展开讨论更新3.04的问题,因为官版tag打的位置有bug,所以现在最好还是等下一个更新版。

  • GPUImage

GPUImage | 不用多说,Github上闻名的几个iOS项目之一。一考虑到本项目需要一些摄像头控制,一些图片的调整,就想到GPUImage会派上用场。

  • OpenCV-iOS

利用机器视觉,识别文档边缘,判断方向,识别照片的视角扭曲,对应作出修改等。

  • ImageMagick

ImageMagick | 对图片的进一步修改/编辑操作,可以使用这个命令行版的“Ps”工具。例如场景:需要对有倾斜拍摄的图片进行视角扭曲,可以很好的利用该工具提供的Perspective Distortion(从平时使用Ps做Perspective Crop裁剪得来灵感)。


定义存储数据类型

当前研究是做ID识别,先定义一个存储ID数据的对象。

满足以下要求:

  • 实现 NSCoding和NSCopying

  • 字段 ID号码,姓名,民族,住址,有效期,签发机关

  • 比较方法 -isEqualToID:

  • 描述方法 -description


组织问题

识别是基于整张图片的,所以即使正确识别出所有文字,引擎也无法分辨谁是谁。
所以如果希望区分内容,请在识别之前,对图片进去分割。

分类
dev

iOS Project with Dependency Manager

Notice: 当前Apple为Swift正在准备一套包管理器,详情参见Github

依赖管理器 Dependency Manager 和 包管理器 Package Manager 

Cocoapods 依赖管理器 Dependency Manager
cocoapods.org/
官方简介:

CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over eighteen thousand libraries and can help you scale your projects elegantly.

官方安装是通过gem源进行的。

但是有以下几点缺点:
gem install需要sudo权限。
默认的gem源https://rubygem.org/国内环境无法访问。淘宝提供的gem镜像也并不稳定。

使用Homebrew包管理器安装

关于Homebrew:(如果已用,请跳过此节)
brew.sh
官方的一点介绍:

Homebrew installs the stuff you need that Apple didn’t.

Homebrew installs packages to their own directory and then symlinks their files into /usr/local.

Homebrew won’t install files outside its prefix, and you can place a Homebrew installation wherever you like.

Trivially create your own Homebrew packages.

It's all git and ruby underneath, so hack away with the knowledge that you can easily revert your modifications and merge upstream updates.

Homebrew formulae are simple Ruby scripts

Homebrew complements OS X. Install your gems with gem, and their dependencies with brew.

强烈推荐Mac环境下使用Homebrew包管理器,而非MacPorts。
Homebrew已有的formula参见:
https://github.com/Homebrew/homebrew-core/tree/master/Formula

安装Homebrew:

Terminal(终端)中粘贴并运行此命令:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

以后需要查找包,直接使用搜索命令:
brew search …

安装包:
brew install …

检查Homebrew状态:
brew doctor

这里我们将使用Homebrew来安装Cocoapods。
brew search cocoapods
可以看到结果里有Cocoapods
那直接brew install cocoapods
等待安装完成~

测试一下Cocoapods是否安装成功,运行命令:
pod
返回结果里有pod正确的使用方法解释,看来是安装成功了。
以后pod升级也不用再sudo gem install了。

使用官方gem安装方法的请注意了:
Cocoapods安装需要sudo权限。但是平时pod时一定不要用sudo。
特别是第一次初始化pod repos的时候,如果使用sudo,将会导致一系列问题,(其实都是权限不对导致)。

使用brew install的,本身不用sudo,不用担心这个问题。

关于Spec repos
初次安装Cocoapods将会克隆一份spec repository到本地。
因为该项目又大文件夹又多,可能容易中断。

实际Spec项目就在Github,链接:
https://github.com/CocoaPods/Specs.git
可以git clone该项目到本地,或者下载zip文件的方式获取它。

将整个repo命名成master,然后放到~/.cocoapods/repos/下即可。

这个时候,再跑一遍命令以完成Cocoapods的初始化:
pod setup

来替代Spec仓库初始化命令的操作。

使用Cocoapods控制第三方库依赖

在Xcode Project目录下,运行pod init命令,将初始化一个Podfile文件。

向其中添加pod库即可。

修改完成后,运行pod install命令,将依据此Podfile生成工程 workspace,包含配置好的所有库。

命令都会输出应有的操作提示。

Where To Go

关于该依赖管理器,还有很多运用,比如自建私有的Pods仓库,本地引用,透过Git引用等。

骆昱
2016-07-05

分类
dev

Objective-C编码规范

Objective-C Coding Standard | Objective-C编码规范

Version 1.0.0
Author Luo Yu
Date Friday, June 24, 2016

本标准的制定参考了Apple官方文档Cocoa Programming Guidelines,Raywenderlich.com Objective-C style guide,Google's Objective-C Coding Standard。

空格

对齐

关于对齐方式,请永远使用Tab,而非空格。

页宽

Page Guide设置为120。
Objective-C的常用长命名方式,再加之当今显示器有更宽的显示范围,这里将页宽调整为120。
可以在Xcode->Preferences->Text Editing->Editing中修改。

请移除行尾多余的空格。

变量

对象类型与*号之间空格,其他不空格。如:
NSString *oneString;

属性声明时,@property后空格,)后空格,对象类型与*号之间空格,其他不空格。如:
@property (nonatomic, strong) NSString *aString;

方法声明

方法类型符号后空一格,返回类型的括号后与方法名之间不空格。如:
- (void)someMethod;
+ (void)someClassMethod;

方法命名时,传参冒号前后都不空格。如:
- (void)someMethod:(NSString *)aString andColor:(UIColor *)aColor;

方法名较长,或参数过多而需换行显示时,优先采取冒号对齐方式。例如:
- (void)someMethodWithParameterOne:(int)paramOne
andParameterTwo:(int)paramTwo;

如冒号对齐无法对齐时,可采用左对齐。

方法调用

空格的采用方式和方法声明时保持一致,冒号前后都无空格。如:
[theObject someMethodWithParameter:1 andParameterTwo:2];

多行调用也与声明的对齐规则一样,优先采用冒号对齐。如:
[theObject someMethodWithParameter:1
          andParameterTwo:2];

关于调用方法时,语法空格的理解。

这是一条最简单Objective-C调用方法时的语法,
[object callMethod];
对象 调用 方法,中间有一个空格。

所以一个连环调用:
[[object callMethodOne] callMethodTwo];
相当于object2 = [object callMehtodOne];
然后有[object2 callMethodTwo];

所以一个不合规范的写法:
[[object callMethodOne]callMethodTwo];
无异于[object2callMethodTwo];
这种不规范的空格简直不能忍。

代码组织

方法分类

使用#pragma mark来分类方法,该标记能在Xcode的代码编辑器中梳理展示。
- 会产生水平分割线
| 可退一格

命名

沿用Objective-C的长命名方式,不推荐缩写。如:
UIImage *caseIconImage;
而不推荐:
UIImage *caseIcoImg;

使用全大写的Prefix。
类名,常量名都应该使用此种Prefix开头。如:
LYObject

常用语法格式

条件语句

if后空格,)后也空格,{不换行。如:
if (!error) {
    // do something ...
}

if语句总是使用{},即使只有一行代码。

else和while遵循同样的规则,在同一行起始{,在新一行结束}。

三元判断时,条件部分使用括号包括。如:
(val == NO) ? case1 : case2;
三元判断语句请勿嵌套使用。

switch语句

switch语句总包含default情况。
switch的case中,总是使用{}包含。

枚举

使用SDK推荐的NS_ENUM()创建枚举类型。避免在Cocoa/Cocoa Touch中使用CF C风格的enum。例如:
typedef NS_ENUM(NSInteger, LYCellType) {
    LYCellTypeHeader,
    LYCellTypeNormal,
    LYCellTypeDisabled,
    LYCellTypeFooter,
};

常量

推荐使用FOUNDATION_EXPORT配合const指定常量,或是static配合const。

尽量避免使用#define的方式。

注释

推荐必要的注释。

注释根据项目要求添加。

为了防止文本文件的编码解码导致的乱码,注释推荐使用英文,但不强制。

分类
dev

Take Ownership REG TEXT

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\takeownership]
@="Take ownership"
"HasLUAShield"=""
"NoWorkingDirectory"=""

[HKEY_CLASSES_ROOT\*\shell\takeownership\command]
@="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"
"IsolatedCommand"="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"

[HKEY_CLASSES_ROOT\exefile\shell\takeownership]
@="Take ownership"
"HasLUAShield"=""
"NoWorkingDirectory"=""

[HKEY_CLASSES_ROOT\exefile\shell\takeownership\command]
@="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"
"IsolatedCommand"="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"

[HKEY_CLASSES_ROOT\dllfile\shell\takeownership]
@="Take ownership"
"HasLUAShield"=""
"NoWorkingDirectory"=""

[HKEY_CLASSES_ROOT\dllfile\shell\takeownership\command]
@="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"
"IsolatedCommand"="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"

[HKEY_CLASSES_ROOT\Directory\shell\takeownership]
@="Take ownership"
"HasLUAShield"=""
"NoWorkingDirectory"=""

[HKEY_CLASSES_ROOT\Directory\shell\takeownership\command]
@="cmd.exe /c takeown /f \"%1\" /r /d y && icacls \"%1\" /grant administrators:F /t"
"IsolatedCommand"="cmd.exe /c takeown /f \"%1\" /r /d y && icacls \"%1\" /grant administrators:F /t"