i沙漏

记录自己学习的点滴

Cocos2d v2.0源码分析

Cocos2d中的关键类及继承关系(以下讨论只涉及iOS版本,不考虑mac版)

CCDirector继承自UIViewController

CCNode继承自NSObject

CCLayer继承自CCNode

CCScene继承自CCNode

Expressjs及mongoose入门

expressjs 调试

如果使用

$ node app.js

的方式运行服务,每次更改服务器代码时都需要手动结果程序然后再运行,显然在开发阶段更改代码是很频繁的。使用supervisor帮忙省下这些麻烦,一但文件更改,supervisor将自动加载。

$ sudo npm install supervisor -g
$ supervisor app.js

用NSLogger代替NSLog输出调试信息

安装

NSLogger分为两部分,LoggerClientNSLogger Viewer,你的App需要导入前者,后者是一个独立的mac应用,NSLogger所有的调试信息将输出到这个应用中。

安装NSLogger:

$ vim Podfile
pod 'NSLogger', '1.1'

$ pod install

如果你不了解Pod,可以参考这里

编译NSLogger Viewer

我在第一次编译时,系统出现了这个错误信息:

Code Sign error: The identity '3rd Party Mac Developer Application' doesn't match any valid, non-expired certificate/private key pair in your keychains

只需将Build Settings => Code Signing Identity 设置为Don't Code Sign

编译通行过后会在项目的Products生成一个NSLogger.app的文件,只须把该文件拷贝到应用目录即可。

使用NSLogger

在需要用到NSLogger的程序导入LoggerClient.h头文件,一般可在ProjectName_Prefix.pch文件导入:

#import "LoggerClient.h"

现在可以用LogMessage等函数来代替NSLog了,更简单的方法是编写一个宏:

#define NSLog(...) LogMessageF( \
        __FILE__,           \
        __LINE__,           \
        __FUNCTION__,       \
        nil, 0,             \
        __VA_ARGS__)

这样,你所有使用NSLog的地方将自动被LogMessageF取代。

iOS应用使用QQ、新浪微博为第三方登录

QQ登录SDK最重要的两个类分别为:TencentOAuthTencentRequest,前者用于向服务器请求登录,后者用于包含请求信息。目前QQ登录在移动应用还没有采用SSO方式,未来应该会跟进。

ControllerView类中声明一个类型为TencentOAuth的实例变量,并在- (void)viewDidLoad方法中初始化:

_tencentOAuth = [[TencentOAuth alloc] initWithAppId: @"your app id" andDelegate: self];

TencentOAuth接受的Delegate为TencentSessionDelegate类型。所以ControllerView对象必须实现TencentSessionDelegate委托。该委托声明了如下方法:

- (void)tencentDidLogin;
// 登录成功

- (void)tencentDidLogout;
// 已退出

- (void)tencentDidNotLogin: (BOOL);
// 登录失败,一种为用户单击了取消按钮。

- (void)tencentDidNotNetwork;
// 没有网络

实现上面的所有方法,接下来向服务器发出认证请求

[_tencentOAuth authorize:_permissions inSafari:NO];

_permissions是一个数组,数组的每一项代表用户授权的OpenAPI列表,例如可以发表微博,发表说说等。inSafari是否需要在safari中进行登录,默认为NO;

Weibo登录

新浪微博已经采用了SSO登录模式,SSO即Single Sign On,单点登录。在官方库中,SinaWeiboSinaWeiboRequest是两个最重的类,首先声明一个SinaWeibo实例变量:

SinaWeibo *weiboOAth;

创建SinaWeibo实例:

weiboOAuth = [[SinaWeibo alloc] initWithAppKey:kAppKey appSecret:kAppSecret appRedirectURI:kAppRedirectURI andDelegate: delegate];

待续…

我最常用的git命令

文件管理

添加新增文件或已修改文件到暂存

$ git add filename

有多个文件更改时

$ git add .

提交更新

$ git commit -m 'msseage'

有时候我们把一些不需要加入版本控制的文件也加入了git库,如何把库中的文件删除,即又保留本地的文件呢?

$ git rm --cached filename

如果使用git rm filename的话本地文件也将一并删除.

删除文件之后我们一般都要将该文件名加入.gitignore文件中。可以参考gitignore,哪种项目需要忽略哪些文件都已经列出。下载相应的项目类型文件,将文件名改为.gitignore即可。

库管理

在本地初始化一个库

$ cd dir
$ git init

从远程克隆一个库

$ git clone git://github.com/lintide/jekyll

上面克隆的库是只读的,如果你对该库拥用写权限,可以使用git remote set-url修改上面的远程地址

$ git remote -v
origin git://github.com/lintide/jekyll

$ git remote set-url origin git@github.com:username/jekyll

username是你在github.com的用户名,git@github.com表示采用ssh登录github.com,这样你就不需要每次都输入用户名了。关于ssh登录的配置方法可以参考其它文章。

打标签

$ git tag -a v1.0.0 -m "version 1.0.0"

显示所有标签

$ git tag

提交标签不是使用git commit命令,而是

$ git push --tags

边学边用边记,持续更新中…

如何编写一个CocoaPods的spec文件

CocoaPods命令介绍

上一篇文章中,已经介绍过CocoaPods的几条基本命令。pod setup用于初始化本地第三方库的Spec描述文件,所有的spec文件存都存放在~/.cocoapods目录中。pod install用来安装或删除Podfile文件声明中的第三方依赖库。下面继续介绍其它一些命令。

$ pod list
# 列出所有可用的第三方库

$ pod search query

搜索名称包含query的类库,query可以替换为你想搜索的名字(如json),不区分大小写。也可以使用pod search --full query命令作更仔细的搜索,该命令不但搜索类库的名称,同时还搜索类库的描述文本,所以搜索速度也相对慢一些。

pod listpod search命令只搜索存在于本地~/.cocoapods文件夹的所有第三方库,并不会连接到远程服务器。如果你要从服务器更新本地第三方库的描述文件,可以:

$ pod repo update master

创建自己项目的Podspec描述文件

CocoaPods还是一个相对年轻的项目,所有的项目的Podspec文件都托管在https://github.com/CocoaPods/Specs。可能有一些库并未收录其中。下面我们通过为微博sso认证登录库编写Podspec文件来学习相关的概念。

初始化一个Podspec文件

$ pod spec create weibo_ios_sdk_sso-oauth

该命令将在本目录产生一个名为weibo_ios_sdk_sso-oauth.podspec的文件。用编辑器打开该文件,里面已经有非常丰富的说明文档。下面我们介绍如何声明第三方库的代码目录资源目录,还有该第三方库所依赖ios核心框架和第三方库。

去除所有的注释,podspec文件如下所示:

Pod::Spec.new do |s|
  s.name     = 'ADVProgressBar'
  s.version  = '0.0.1'
  s.license  = 'MIT'
  s.summary  = 'Progress Bar Design with Percentage values.'
  s.homepage = 'https://github.com/appdesignvault'
  s.author   = { 'appdesignvault' => 'appdesignvault' }
  s.source   = { :git => 'https://github.com/appdesignvault/ADVProgressBar.git', :commit => 'f17b15c15574d6d101cd5fcfd58239e16e806647' }
  s.platform = :ios  
  s.source_files = 'ADVProgressBar/Classes/*.{h,m}'
  s.resources = "ADVProgressBar/Resources/*.png"
  s.framework = 'UIKit'

  s.requires_arc = true  
end

其中s.names.summary用来声明库的名称和一个简短的说明文档。pod search命令就是根据这两项内容作为搜索文本的。s.homepage声明库的主页,s.version库原代码的版本,s.license所采用的授权版本,s.author库的作者。

s.source 声明原代码的地址,以微博sso认证登录库为例,它托管在https://github.com/mobileresearch/weibo_ios_sdk_sso-oauth中,在其未尾加上.git扩展名就是库的原代码地址了,所以该行应声明为:

s.source = { :git => 'https://github.com/mobileresearch/weibo_ios_sdk_sso-oauth.git'}

对于很多第三方库而言,在发布的时候都会打上一个tag,如版本0.0.1就会打上一个名为v0.0.1tag,但是weibo_ios_sdk_sso-oauth库还未打上所何tag,我们可以选择一个最新的commit来作为该库0.0.1版的代码。s.source最终如下:

s.source = { :git => 'https://github.com/mobileresearch/weibo_ios_sdk_sso-oauth.git', :commit => '68defea78942ecc782ffde8f8ffa747872af226d'}

以后我们可以根据该库不同的版本创建相应的podspec文件,例如0.0.20.1.0等。

让我们在浏览器中看一下weibo_ios_sdk_sso-oauth的目录结构:

--
|
+-- demo
|
+-- src
|
+-- .gitignore
|
+-- README.md

demo目录保存一个示例项目,src才是库的原代码目录。src的目录结构如下:

-- src
    |
    +-- JSONKit
    |
    +-- SinaWeibo
    |
    +-- sinaweibo_ios_sdk.xcodeproj
    |
    +-- SinaWeibo-Prefix.pch

JSONKit目录说明这个库本身依赖于JSONKit第三方库。我们可以在podspec文件中的s.dependency声明段中声明。SinaWeibo目录才是包含所有原代码的目录,我们需要在s.source_files中声明

s.source_files = 'src/SinaWeibo/*.{h,m}'

前一部分src/SinaWeibo/是一个相对目录,目录的层级关系一定要跟代码库的保持一致。最后一部分*.{h,m}是一个类似正则表达式的字符串,表示匹配所有以.h.m为扩展名的文件。

src/SinaWeibo/目录下还有一个SinaWeibo.bundle目录,该目录存放一些资源文件(如图片等),这些文件并不需要进行编译。可以使用s.resourcs声明

s.resources = "src/SinaWeibo/SinaWeibo.bundle/**/*.png"

前一部分跟上面相同,**表示匹配所有子目录,*.png表示所有以.png为扩展名的图片文件。

通过查看代码我们知道,weibo_ios_sdk_sso-oauth还依赖一个ios的核心库QuartzCore

s.framework = 'QuartzCore'

在前面我们已经说过,weibo_ios_sdk_sso-oauth库自身也依赖于另外一个第三方库JSONKit,声明如下:

s.dependency 'JSONKit', '~> 1.4'

这行声明与Podfile文件中的声明类似。

最终的结果如下:

Pod::Spec.new do |s|
  s.name         = "weibo_ios_sdk_sso-oauth"
  s.version      = "0.0.1"
  s.summary  = 'weibo.com sso oauth, 微博sso认证登录功能'
  s.homepage     = "https://github.com/mobileresearch/weibo_ios_sdk_sso-oauth"
  s.license      = 'MIT'
  s.author       = {'mobileresearch' => 'mobileresearch'}
  s.source       = { :git => 'https://github.com/mobileresearch/weibo_ios_sdk_sso-oauth.git', :commit => '68defea78942ecc782ffde8f8ffa747872af226d' }
  s.platform = :ios
  s.source_files = 'src/SinaWeibo/*.{h,m}'
  s.resources = "src/SinaWeibo/SinaWeibo.bundle/**/*.png"
  s.framework  = 'QuartzCore'
  s.dependency 'JSONKit', '~> 1.4'
end

可以将该spec文件保存到本机的~/.cocoapods/master/目录中仅供自己使用,也可以将其提交到CocoaPods/Specs代码库中。下面我们将其保存到本机中

$ mkdir -p ~/.cocoapods/master/weibo_ios_sdk_sso-oauth/0.0.1
$ cp weibo_ios_sdk_sso-oauth.podspec ~/.cocoapods/master/weibo_ios_sdk_sso-oauth/0.0.1

是否可以通过搜索找到该库:

$ pod search weibo

同样在需要依赖于weibo_ios_sdk_sso-oauth这个库的项目,可以将下列添加到项目的Podfile文件中

pod 'weibo_ios_sdk_sso_oauth', '0.0.1'

保存文件,并用pod install安装weibo_ios_sdk_sso-oauth库。

转载请注明原作者

使用Octopress + Github管理blog

准备

用Octopress来管理blog是要点耐心的,我就有几次想要放弃,因为涉及的概念很多。当然对于头上顶着hacker这个词的人,再难的困难都能克服。

要使用octopress和github来管理blog,你得懂一点点ruby(jekyll), 并且使用过github,然后还要懂一些git命令,学习Markdown来写文章。就这些,言归正传。(注:如果你输入下列的命令发现该命令未找到的时候,请自行google并安装之,恕不一一介绍)。确保你的系统已经安装了下列程序

  • git
  • ruby (1.9.3) 和 rvm 和 (bundle)

安装

$ git clone https://github.com/imathis/octopress.git myblog

注意,后面的myblog你可以取任何你想要的名称。

让我们来看看这个目录里现在包含了什么:

$ cd myblog
$ ls

显示如下:

CHANGELOG.markdown  README.markdown     config.rb
Gemfile         Rakefile        config.ru
Gemfile.lock        _config.yml     plugins

先不用理解这些文件都代表什么意思,继续:

$ bundle install

安装octopress信赖的ruby库,完成后进行初始化:

$ rake install

现在看看目录里有哪些文件

$ ls

显示如下:

CHANGELOG.markdown  Rakefile        plugins
Gemfile         _config.yml     public
Gemfile.lock        config.rb       sass
README.markdown     config.ru       source

我们看到,系统新增了两个文件夹,publicsourcesource文件夹就是我们以后工作的目录,source中有个_posts文件夹,这就是保存每一篇blog的地方了;而对于public文件夹,我们不需要直接操作它,它将由系统自动生成。

现在我们可以新增blog了。

$ rake new_post["hello world"]

这个命令将在 source/_posts/文件夹下生成一个类似yyyy-mm-dd-hello-world.markdown的文件,其中yyyy-mm-dd为系统当前的日期,而扩展名表示这是个Markdown文件。你可以选择你喜欢的文本编辑器来修改这个文件。强烈推荐Sublime Text 2。将下列文本添加到该文件的末尾中,先不管其中的符号代表什么.

## Hello world ##

来看看我们的成果吧

$ rake preview

Octopress在本机中开启了一个服务器,打开浏览器看看http://localhost:4000。一切正常:)

如果你现在打开public这个文件夹,将会看到很多新增的文件。这些文件不需要我们的管理,当然理解它也是有意义的。

在github中托管blog

到目前我止,我们的blog仅能在本机中访问,如何将其托管到github中呢?如何使用我们自己的域名呢?让一切看起来就如同我们自己的站点。

如果你要使用自己的域名,github需要一个CNAME文件,进入source文件夹,新建CNAME文件。

$ ch source
$ touch CNAME

将你的域名写入CNAME文件中,如myblog.com。你还需要到你的域名管理中心中新增一个A Record,并指向207.97.227.245IP。

托管到github中

$ rake setup_github_pages

系统提示你输入一个形如:git@github.com:username/myblog.com.git,username是你在github.com中注册的用户名,myblog.com.git是你自己在github.com中创建的代码库。输入后按回车确定.

现在再看看我们的文件夹:

$ ls

系统新增了一个文件夹_deploy,其实这个文件夹本身也是一个git代码库,你可以使用ls -a命令,将看到一个名为.git的文件夹,这个文件夹表示这是个git库(不要修改里面的内容)。 现在可以向github提交我们的网站了.

$ rake generate
$ rake deploy

如果提示如下错误

## Pushing generated _deploy website
ERROR: Repository not found.
fatal: The remote end hung up unexpectedly

则说明你还没有在github.com中创建形如myblog.com的代码库,到github中创建之。如果一切正常那么恭喜你:)

使用域名访问是否正常。

让我们回过头来到github.com上看一下myblog.com代码库,如果你仔细观察,将会发现这些新增的代码保存在gh-pages分支中(左上角会显示: branch: gh-pages)。这里的代码其实是我们本地计算机_deploy文件夹中的一份拷贝,还记得我们在上面说过吗_deploy其实也是一个git库。

仅仅托管这个文件夹还是不够的,因为我们自己产生的所有文件将保存在source/_posts文件夹中,而顶级目录myblog下也有我们自己的配置文件。我们想把这些都加入代码库中,因为这样才能真正的获得版本控制的好处。你想对你的文章怎么修改都行,只要你向服务器提交了更改,总可以回退到以前的某一个版本。

那么?要怎么做才合理呢?还是向大师学习吧,Octopress的大师是谁?那就是Octopress自身了,我们到https://github.com/imathis/octopress上看看吧,点击左上角branch: master的向下按钮,你们看到很多个brach的名称,其中就有gh-pages分支,还有mastersite等等。点击site这个分支看看。是不是跟我们本地的myblog文件夹很像呢?也有sourceplugins,sass等文件夹和_config.yml等配置文件。不过少了两个文件_deploypublic,这两个文件夹恰恰就是我们不需要进行版本控制的,因为_deploy就是我们在gh-pages分支中的代码,而public是用于我们在本地机器预览时用到的。那它是怎么做到的呢?让我们来看看究竟。

进入myblog这个目录,然后

$ ls -a

哦,好多文件。其中以.开头的是隐藏文件,当使用ls命令时是无法看到。对我们而言,重要的是.git文件夹和.gitignore文件。上面我们说过.git文件夹表明这是个git代码库。.gitignore是用来声明哪些文件或文件夹不需要加入git版本控制中。看看它里面有什么:

$ cat .gitignore

显示如下:

.bundle
.DS_Store
.sass-cache
.gist-cache
.pygments-cache
_deploy
public
sass.old
source.old
source/_stash
source/stylesheets/screen.css
vendor
node_modules

里面显示的文件或文件夹都不会出现在git代码库中,其中就有_deploypublic,这些正是我们所需要的。拿来即用。看看当前的代码库的状态:

$ git status

将显示有哪些文件未加入代码库中,可以使用git addgit commit命令。如果对git不是很理解,建议看git简易指南

如何将这个代码库也向Octopress一样提交到我们自己的site分支中呢?

$ git remote add origin git@github.com:username/myblog.com.git

git@github.com:username/myblog.com.git必须跟你自己在上面使用的代码库地址一致。

$ git branch -m site
$ git push origin site

一切正常:),看看github中的代码库,现在是不是有两个分支了呢?gh-pagessite

发表blog的流程

  1. rake new_post["new post name"]命令新建blog文章.
  2. 用Sublime Text 2编辑新建的blog.
  3. rake preview在本机中预览。
  4. rake generaterake deploy上传到github.com
  5. 同时用git add, git commit, 和git push origin site 提交site分支的更改.

就这些…

参考文档

octopress

github pages

Blog = Github + Octopress

git简易指南

像黑客一样写博客

使用CocoaPods管理iOS的第三方类库

iOS第三方类库的管理是一个很麻烦的事,项目信赖的类库和版本很难控制。让CocoaPods 来帮帮我们吧。

安装

先确认自己是否安装了ruby的运行环境,若没有则安装之。接着:

$ gem install cocoapods
$ pod setup

使用

  • 用Xcode新建一个iOS新项目,创建后目录结果如下:(项目名为:App)

      App
        |
        +- App
        |
        +- App.xcodeproj
    
  • 进入顶层App目录

      $ cd ~/App
    
  • 新建一个名为 Podfile 的文件

      $ touch Podfile
      $ vi Podfile
    

    输入以下内容,并保存

    platform :ios

    pod ‘JSONKit’, ‘~>1.4’

    pod ‘Reachability’, ‘~>2.0.4’

      $ pod install
    

    cocoaPods将自动从服务器中拉取相应的第三方库原代码,将其存放在Pods目录中。

  • 现在目录结构如下:

      App
        |
        +- App
        |
        +- App.xcodeproj
        |
        +- App.xcworkspace
        |
        +- Podfile
        |
        +- Podfile.lock
        |
        +- Pods
    

    其中 Pods目录是一个xcode项目,里面包含所有在Podfile中声明的第三方库代码。App.xcworkspace 为xcode的工作空间文件,以后用这个文件来打开项目。

      $ open App.xcworkspace
    
  • Podfile.lock 文件记录所有已安装的代码库的描述,文件如下:

      PODS:
      - JSONKit (1.5pre)
      - Reachability (2.0.5)
    
      DEPENDENCIES:
      - JSONKit (~> 1.4)
      - Reachability (~> 2.0.4)
    
      SPEC CHECKSUMS:
       JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
       Reachability: 8d29c8365f72967b6decc8d2892a7d5dc6550799
    

    不要更改这个文件的内容。如果要添加或者删除代码库,在Podfile文件里增加或删除pod声明就可以了。现在第三方库管理起来是不是方便多了呢?