Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
1268 lines (807 sloc) 73.9 KB
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Code for fun</title>
<meta name="author" content="liwh">
<meta name="description" content="最近,想折腾下nodejs,所以,就想折腾一下nodejs搭建一个blog,现在支持nodejs的主机也还有不少的。比如,heroku目前就支持nodejs的主机,当然,还有其它的一些了。 如何开始 这次,我们选用 node + express(类似ruby的sinatra框架) + &hellip;">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="http://liwh.github.com">
<link href="/favicon.png" rel="icon">
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
<script src="/javascripts/modernizr-2.0.js"></script>
<script src="/javascripts/ender.js"></script>
<script src="/javascripts/octopress.js" type="text/javascript"></script>
<link href="/atom.xml" rel="alternate" title="Code for fun" type="application/atom+xml">
<!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20088141-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body >
<header role="banner"><hgroup>
<h1><a href="/">Code for fun</a></h1>
<h2>Do It Right Now!</h2>
</hgroup>
</header>
<nav role="navigation"><ul class="subscription" data-subscription="rss">
<li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
</ul>
<form action="http://google.com/search" method="get">
<fieldset role="search">
<input type="hidden" name="q" value="site:liwh.github.com" />
<input class="search" type="text" name="q" results="0" placeholder="Search"/>
</fieldset>
</form>
<ul class="main-navigation">
<li><a href="/">Blog</a></li>
<li><a href="/blog/archives">Archives</a></li>
<li><a href="/about">About Me</a></li>
</ul>
</nav>
<div id="main">
<div id="content">
<div class="blog-index">
<article>
<header>
<h1 class="entry-title"><a href="/blog/2012/01/18/create-blog-with-nodejs/">用NodeJS创建博客</a></h1>
<p class="meta">
<time datetime="2012-01-18T14:07:00+08:00" pubdate data-updated="true">Jan 18<span>th</span>, 2012</time>
</p>
</header>
<div class="entry-content"><p>最近,想折腾下nodejs,所以,就想折腾一下nodejs搭建一个blog,现在支持nodejs的主机也还有不少的。比如,<a href="http://devcenter.heroku.com/articles/node-js">heroku</a>目前就支持nodejs的主机,当然,还有其它的一些了。</p>
<h4>如何开始</h4>
<p>这次,我们选用 node + express(类似ruby的sinatra框架) + mongoDB(NoSQL数据库). 一般来说,express我们一般用npm(node的包管理)进行安装,只有下面简单的命令就可以了。</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>sudo node install express -g
</span></code></pre></td></tr></table></div></figure>
<h4>实现功能</h4>
<p>在这里,我们主要为了实现功能:</p>
<ul>
<li>创建新文章</li>
<li>展示所有文章列表</li>
</ul>
<h4>具体步骤</h4>
<p>下面,我们就介绍详细的具体步骤。</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mkdir blog
</span><span class='line'><span class="nb">cd </span>blog
</span><span class='line'>express -c stylus <span class="c">#创建使用jade模版引擎和stylus css引擎的应用</span>
</span><span class='line'>npm install -d <span class="c">#下载所依赖的包</span>
</span></code></pre></td></tr></table></div></figure>
<h4>构建对应的ORM,用于处理文章的CRUD操作</h4>
<p>首先,我们得构建对应的操作来处理文章的crud操作,代码如下:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">mongoose</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">MONGOLAB_URI</span> <span class="o">||</span> <span class="s1">&#39;mongodb://localhost/blog&#39;</span><span class="p">);</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">Article</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="s1">&#39;Blog&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">({</span>
</span><span class='line'> <span class="nx">title</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span>
</span><span class='line'> <span class="nx">body</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span>
</span><span class='line'> <span class="p">}));</span>
</span><span class='line'><span class="c1">//具体的crud可参照 https://github.com/LearnBoost/mongoose#readme</span>
</span></code></pre></td></tr></table></div></figure>
<h4>新增文章</h4>
<p>首先,我们定义请求/blogs/new页面为新增的页面。 在此页面存在表单元素title和body.我们通过填写对应的内容,然后发送post请求,增加对应的内容。具体代码如下:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/blogs/new&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="nx">res</span><span class="p">){</span>
</span><span class='line'> <span class="nx">res</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">&#39;blog_new.jade&#39;</span><span class="p">,{</span><span class="nx">locals</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">title</span><span class="o">:</span> <span class="s2">&quot;新增文章&quot;</span><span class="p">,</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/blogs/new&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">){</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">article</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Article</span><span class="p">({</span><span class="nx">title</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">param</span><span class="p">(</span><span class="s1">&#39;title&#39;</span><span class="p">),</span> <span class="nx">body</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">param</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">)});</span>
</span><span class='line'> <span class="nx">article</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span>
</span><span class='line'> <span class="kd">function</span><span class="p">(</span> <span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;there is a error occured!&quot;</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">);</span>
</span><span class='line'> <span class="nx">res</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<h3>查看文章</h3>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/blogs/:id&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="nx">res</span><span class="p">){</span>
</span><span class='line'> <span class="nx">articles</span> <span class="o">=</span> <span class="nx">Article</span><span class="p">.</span><span class="nx">find</span><span class="p">({});</span>
</span><span class='line'> <span class="nx">Article</span><span class="p">.</span><span class="nx">findById</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">article</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">res</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">&#39;show.jade&#39;</span><span class="p">,{</span><span class="nx">locals</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">title</span><span class="o">:</span> <span class="nx">article</span><span class="p">.</span><span class="nx">title</span><span class="p">,</span>
</span><span class='line'> <span class="nx">body</span><span class="o">:</span> <span class="nx">article</span><span class="p">.</span><span class="nx">body</span><span class="p">,</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'> <span class="p">})</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<h4>参考资料</h4>
<ul>
<li><a href="http://blog.xebia.com/2011/06/24/getting-started-with-node-js-npm-coffeescript-express-jade-and-redis/">node jade</a></li>
<li><a href="http://howtonode.org/express-mongodb">Blog rolling with mongoDB, express and Node.js</a></li>
<li><a href="https://github.com/LearnBoost/mongoose">mongoose</a></li>
</ul>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2012/01/09/how-to-add-image-to-map-pin/">给地图大头针加图片</a></h1>
<p class="meta">
<time datetime="2012-01-09T13:26:00+08:00" pubdate data-updated="true">Jan 9<span>th</span>, 2012</time>
</p>
</header>
<div class="entry-content"><p>我们在IPhone中使用谷歌地图的时候,我们可以在地图中插入大头针。这些大头针左边显示了图片,右边一般显示>标记,用于显示更加详细的信息。
下面,介绍下,如何在大头针中加图片。</p>
<p>每个Annotations都可以用一个callout用于显示信息, 默认,我们点击的时候,只显示 <strong>title</strong> 和 <strong>subtitle</strong> ,但是,我们可以为它增加
左边和右边的accessory视图。一般,我们左侧会增加图片,右边一般增加一个UIButton(UIButtonTypeDetailDisclosure).下面,介绍如何增加:</p>
<ul>
<li>首先,给地图控制器增加下面方法,用于设置图片</li>
</ul>
<figure class='code'><figcaption><span>MapViewController.m</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='obj-c'><span class='line'><span class="o">-</span><span class="p">(</span><span class="n">MKAnnotationView</span> <span class="o">*</span><span class="p">)</span><span class="nl">mapView:</span><span class="p">(</span><span class="n">MKMapView</span> <span class="o">*</span><span class="p">)</span><span class="n">mapView</span> <span class="nl">viewForAnnotation:</span><span class="p">(</span><span class="kt">id</span><span class="o">&lt;</span><span class="n">MKAnnotation</span><span class="o">&gt;</span><span class="p">)</span><span class="n">annotation</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="c1">//为针上增加左侧图片</span>
</span><span class='line'> <span class="n">MKAnnotationView</span> <span class="o">*</span><span class="n">aView</span> <span class="o">=</span> <span class="p">[</span><span class="n">mapView</span> <span class="nl">dequeueReusableAnnotationViewWithIdentifier:</span><span class="s">@&quot;MapVC&quot;</span><span class="p">];</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">aView</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="n">aView</span> <span class="o">=</span> <span class="p">[[</span><span class="n">MKPinAnnotationView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithAnnotation:</span><span class="n">annotation</span> <span class="nl">reuseIdentifier:</span><span class="s">@&quot;MapVC&quot;</span><span class="p">];</span>
</span><span class='line'> <span class="n">aView</span><span class="p">.</span><span class="n">canShowCallout</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'> <span class="n">aView</span><span class="p">.</span><span class="n">leftCalloutAccessoryView</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIImageView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithFrame:</span><span class="n">CGRectMake</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">30</span><span class="p">)];</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="n">aView</span><span class="p">.</span><span class="n">annotation</span> <span class="o">=</span> <span class="n">annotation</span><span class="p">;</span>
</span><span class='line'> <span class="p">[(</span><span class="n">UIImageView</span> <span class="o">*</span><span class="p">)</span><span class="n">aView</span><span class="p">.</span><span class="n">leftCalloutAccessoryView</span> <span class="nl">setImage:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'> <span class="k">return</span> <span class="n">aView</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="o">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">mapView:</span><span class="p">(</span><span class="n">MKMapView</span> <span class="o">*</span><span class="p">)</span><span class="n">mapView</span> <span class="nl">didSelectAnnotationView:</span><span class="p">(</span><span class="n">MKAnnotationView</span> <span class="o">*</span><span class="p">)</span><span class="n">aView</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="n">UIImage</span> <span class="o">*</span><span class="n">image</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">delegate</span> <span class="nl">mapViewController:</span><span class="n">self</span> <span class="nl">imageForAnnotation:</span><span class="n">aView</span><span class="p">.</span><span class="n">annotation</span><span class="p">];</span>
</span><span class='line'> <span class="p">[(</span><span class="n">UIImageView</span> <span class="o">*</span><span class="p">)</span><span class="n">aView</span><span class="p">.</span><span class="n">leftCalloutAccessoryView</span> <span class="nl">setImage:</span><span class="n">image</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<ul>
<li>设置delegate用于传递所需要显示的图片。</li>
</ul>
<p>具体代码可参见<a href="https://github.com/liwh/PhotoDetail/commit/f90a44a5168a2ca5e2728ab3f84b9667132cac00">样例代码</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2012/01/08/how-to-build-cocoa2d-application/">构建cocos2d开发环境</a></h1>
<p class="meta">
<time datetime="2012-01-08T14:26:00+08:00" pubdate data-updated="true">Jan 8<span>th</span>, 2012</time>
</p>
</header>
<div class="entry-content"><p>cocos2d是一个开源框架,用于构建2D游戏、演示程序和其他图形界面交互应用等。参见<a href="http://baike.baidu.com/view/3800461.html?fromTaglist">百科</a></p>
<ul>
<li><p>首先下载相应的<a href="http://www.cocos2d-iphone.org/download">文件</a>,最新的代码可以在github上<a href="https://github.com/cocos2d/cocos2d-iphone">查看</a></p></li>
<li><p>然后,到对应的目录,在termianl下,执行下面命令</p></li>
</ul>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'> ./install-templates.sh -u -f
</span></code></pre></td></tr></table></div></figure>
<ul>
<li><p>然后,在我们创建工程的模版中,我们就嫩看见对应的模版了。如下图所示:
<img src="/images/cocos2d.png" alt="image" /></p></li>
<li><p>最后,我们点xcode的运行,就可以看到如下效果了
<img src="/images/hello_world.png" alt="image" /></p></li>
</ul>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2012/01/06/introduct-ui-gesture-recognizer/">IOS手势操作</a></h1>
<p class="meta">
<time datetime="2012-01-06T15:28:00+08:00" pubdate data-updated="true">Jan 6<span>th</span>, 2012</time>
</p>
</header>
<div class="entry-content"><p>当我们使用IPhone的时候,时常通过我们的手势来操作,比如说,我们通过两指挤压使图片放大缩小等,还有我们通过手指划过改变直线的弯曲程度等等。
这些在IOS中都利用到了UIGestureRecognizer类。</p>
<h4>如何使用</h4>
<ul>
<li>增加一个手势识别方法给UIView。</li>
<li>提供响应的&#8221;handle&#8221;方法处理相应的手势操作。</li>
</ul>
<p>例如,我们在Controller中增加一个手势识别方法给UIView。</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='obj-c'><span class='line'> <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">setPannableView:</span><span class="p">(</span><span class="n">UIView</span> <span class="o">*</span><span class="p">)</span><span class="n">pannableView</span>
</span><span class='line'> <span class="p">{</span>
</span><span class='line'> <span class="n">_pannableView</span> <span class="o">=</span> <span class="n">pannableView</span><span class="p">;</span>
</span><span class='line'> <span class="n">UIPanGestureRecognizer</span> <span class="o">*</span><span class="n">pangr</span> <span class="o">=</span>
</span><span class='line'> <span class="p">[[</span><span class="n">UIPanGestureRecognizer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTarget:</span><span class="n">pannableView</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">pan:</span><span class="p">)];</span> <span class="c1">//为panableView增加手指划过操作</span>
</span><span class='line'> <span class="p">[</span><span class="n">pannableView</span> <span class="nl">addGestureRecognizer:</span><span class="n">pangr</span><span class="p">];</span> <span class="c1">//相当于开启对应的手势操作,如果,不增加这句,前面就算实现了对应的方法,也是不会执行的</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>每种手势操作都提供对应的方法让我们处理对应的事件。例如,UIPanGestureRecognizer就提供了三种方法,如:</p>
<ul>
<li><ul>
<li>(CGPoint)translationInView:(UIView <em>)aView;</em> - (CGPoint)velocityInView:(UIView <em>)aView;</em> - (void)setTranslation:(CGPoint)translation inView:(UIView *)aView;</li>
</ul>
</li>
</ul>
<p>另外,我们就是通过对其state的判断来觉得该处理什么的样的操作了.例如,下面的判断就是说,当我们接触移动,或者停止接触的时候,我们都更新view</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='obj-c'><span class='line'> <span class="k">if</span> <span class="p">((</span><span class="n">gesture</span><span class="p">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">UIGestureRecognizerStateChanged</span><span class="p">)</span> <span class="o">||</span>
</span><span class='line'> <span class="p">(</span><span class="n">gesture</span><span class="p">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">UIGestureRecognizerStateEnded</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'> <span class="n">CGPoint</span> <span class="n">translation</span> <span class="o">=</span> <span class="p">[</span><span class="n">recognizer</span> <span class="nl">translationInView:</span><span class="n">self</span><span class="p">];</span>
</span><span class='line'> <span class="n">self</span><span class="p">.</span><span class="n">origin</span> <span class="o">=</span> <span class="n">CGPointMake</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">x</span><span class="o">+</span><span class="n">translation</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">self</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span><span class="o">+</span><span class="n">translation</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="p">[</span><span class="n">recognizer</span> <span class="nl">setTranslation:</span><span class="n">CGPointZero</span> <span class="nl">inView:</span><span class="n">self</span><span class="p">];</span>
</span><span class='line'> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h4>其它的一些手势操作</h4>
<ul>
<li>UIPinchGestureRecognizer</li>
<li>UIRotationGestureRecognizer</li>
<li>UISwipeGestureRecognizer</li>
<li>UITapGestureRecognizer</li>
</ul>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2012/01/06/how-to-draw-circle/">How-to-draw-circle</a></h1>
<p class="meta">
<time datetime="2012-01-06T00:07:00+08:00" pubdate data-updated="true">Jan 6<span>th</span>, 2012</time>
</p>
</header>
<div class="entry-content"><p>这里介绍,如何实现在UIView中画圆,下面是主要代码:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='obj-c'><span class='line'><span class="o">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">drawCircleAtPoint:</span><span class="p">(</span><span class="n">CGPoint</span><span class="p">)</span><span class="n">p</span> <span class="nl">withRadius:</span><span class="p">(</span><span class="n">CGFloat</span><span class="p">)</span><span class="n">radius</span> <span class="nl">inContext:</span><span class="p">(</span><span class="n">CGContextRef</span><span class="p">)</span><span class="n">context</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="n">UIGraphicsPushContext</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
</span><span class='line'> <span class="n">CGContextBeginPath</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
</span><span class='line'> <span class="n">CGContextAddArc</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">radius</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">M_PI</span><span class="p">,</span> <span class="n">YES</span><span class="p">);</span>
</span><span class='line'> <span class="n">CGContextStrokePath</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
</span><span class='line'> <span class="n">UIGraphicsPopContext</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">drawRect:</span><span class="p">(</span><span class="n">CGRect</span><span class="p">)</span><span class="n">rect</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="c1">// Drawing code</span>
</span><span class='line'> <span class="n">CGContextRef</span> <span class="n">context</span> <span class="o">=</span> <span class="n">UIGraphicsGetCurrentContext</span><span class="p">();</span>
</span><span class='line'> <span class="n">CGPoint</span> <span class="n">midPoint</span><span class="p">;</span>
</span><span class='line'> <span class="n">midPoint</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span> <span class="p">;</span>
</span><span class='line'> <span class="n">midPoint</span><span class="p">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="p">;</span>
</span><span class='line'> <span class="n">CGFloat</span> <span class="n">size</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span> <span class="o">&lt;</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span><span class="p">)</span> <span class="n">size</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="n">CGContextSetLineWidth</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">);</span>
</span><span class='line'> <span class="p">[[</span><span class="n">UIColor</span> <span class="n">redColor</span><span class="p">]</span> <span class="n">setStroke</span><span class="p">];</span>
</span><span class='line'> <span class="p">[</span><span class="n">self</span> <span class="nl">drawCircleAtPoint:</span><span class="n">midPoint</span> <span class="nl">withRadius:</span><span class="n">size</span> <span class="nl">inContext:</span><span class="n">context</span><span class="p">];</span>
</span><span class='line'><span class="err">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>显示如下:</p>
<p><img src="http://ww4.sinaimg.cn/mw600/6757a08cjw1dosny8myysj.jpg" alt="image" /></p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='obj-c'><span class='line'><span class="c1">//Begin the path</span>
</span><span class='line'><span class="err"></span><span class="n">CGContextBeginPath</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">//Move around, add lines or arcs to the path</span>
</span><span class='line'><span class="n">CGContextMoveToPoint</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mi">75</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span><span class='line'><span class="n">CGContextAddLineToPoint</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">150</span><span class="p">);</span>
</span><span class='line'><span class="n">CGContextAddLineToPoint</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">150</span><span class="p">);</span>
</span><span class='line'><span class="c1">//Close the path (connects the last point back to the first) CGContextClosePath(context); // not strictly required</span>
</span><span class='line'>
</span><span class='line'><span class="c1">//Actually the above draws nothing (yet)!</span>
</span><span class='line'><span class="c1">//You have to set the graphics state and then fill/stroke the above path to see anything. [[UIColor greenColor] setFill]; // object-oriented convenience method (more in a moment) [[UIColor redColor] setStroke];</span>
</span><span class='line'><span class="err"></span><span class="n">CGContextDrawPath</span><span class="p">(</span><span class="n">context</span><span class="p">,</span><span class="n">kCGPathFillStroke</span><span class="p">);</span> <span class="c1">//kCGPathFillStrokeisaconstant</span>
</span></code></pre></td></tr></table></div></figure>
<h4>参考资料</h4>
<p><a href="http://www.cocoachina.com/newbie/basic/2012/0106/3840.html">画图代码笔记</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2012/01/03/ios-gcd/">GCD介绍</a></h1>
<p class="meta">
<time datetime="2012-01-03T16:21:00+08:00" pubdate data-updated="true">Jan 3<span>rd</span>, 2012</time>
</p>
</header>
<div class="entry-content"><p>GCD是ios 4.0引入用于在应用程序中管理多个任务执行的技术。是C API的一部分。一般我们将其替代作为应用程序的多线程处理。
GCD的函数一般以&#8221;dispatch_&#8221;开头,我们可以使用这个执行某些后台任务,然后返回处理主线程的代码。</p>
<h4>例子</h4>
<p>下面介绍一个例子,创建gcd队列下载图片:</p>
<p>主要代码:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='obj-c'><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">viewWillAppear:</span><span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="n">animated</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="n">tch_queue_t</span> <span class="n">downloadQueue</span> <span class="o">=</span> <span class="n">dispatch_queue_create</span><span class="p">(</span><span class="err">“</span><span class="n">image</span> <span class="n">downloader</span><span class="err">”</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span><span class='line'> <span class="n">dispatch_async</span><span class="p">(</span><span class="n">downloadQueue</span><span class="p">,</span> <span class="o">^</span><span class="p">{</span>
</span><span class='line'> <span class="n">NSData</span> <span class="o">*</span><span class="n">imageData</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSData</span> <span class="nl">dataWithContentsOfURL:</span><span class="n">networkURL</span><span class="p">];</span>
</span><span class='line'> <span class="c1">//UIKit使用只能在main thread中</span>
</span><span class='line'> <span class="n">dispatch_async</span><span class="p">(</span><span class="n">dispatch_get_main_queue</span><span class="p">(),</span> <span class="o">^</span><span class="p">{</span>
</span><span class='line'> <span class="n">UIImage</span> <span class="o">*</span><span class="n">image</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIImage</span> <span class="nl">imageWithData:</span><span class="n">imageData</span><span class="p">];</span>
</span><span class='line'> <span class="n">self</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="n">image</span><span class="p">;</span>
</span><span class='line'> <span class="n">self</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">frame</span> <span class="o">=</span> <span class="n">CGRectMake</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">image</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span><span class="p">,</span> <span class="n">image</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span><span class="p">);</span>
</span><span class='line'> <span class="n">self</span><span class="p">.</span><span class="n">scrollView</span><span class="p">.</span><span class="n">contentSize</span> <span class="o">=</span> <span class="n">image</span><span class="p">.</span><span class="n">size</span><span class="p">;</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'> <span class="n">dispatch_release</span><span class="p">(</span><span class="n">downloadQueue</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h4>参考资料</h4>
<p><a href="http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/rexerence.html">GCD</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2011/11/05/build-oauth2-provider/">Build-oauth2-provider</a></h1>
<p class="meta">
<time datetime="2011-11-05T20:10:00+08:00" pubdate data-updated="true">Nov 5<span>th</span>, 2011</time>
</p>
</header>
<div class="entry-content"><h3>introduce</h3>
<p>最近,花了一段时间去整理oauth2.0 provider的功能,现在,很多互联网都是通过此方式共享API接口,
例如,豆瓣,新浪等等。其特点是不需要用户在第三方应用中输入用户名、密码即可完成授权操作。现在最新版本是 <a href="http://tools.ietf.org/html/draft-ietf-oauth-v2-22">draft-ietf-oauth-v2-22</a>,具体流程可参考其文档。这里就不赘述其细节了,简单来说就是通过client_id和client_secret还有redirect_uri这几个参数,请求验证服务器的授权,然后通过返回一个可信任的access_token来调用服务器的资源。下面,介绍一下如何在rails 中实现这个流程。</p>
<h3>实现</h3>
<p>在github上查找了几个gem, 最终选定 <a href="https://github.com/songkick/oauth2-provider">oauth2-provider</a> ,下面介绍一下实现方式。</p>
<p>首先,我们创建一个oauth_controller,添加下面代码</p>
<figure class='code'><figcaption><span>oauth_controller.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">OauthController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
</span><span class='line'> <span class="k">def</span> <span class="nf">authorize</span> <span class="c1"># 返回authorize_code</span>
</span><span class='line'> <span class="vi">@oauth2</span> <span class="o">=</span> <span class="no">OAuth2</span><span class="o">::</span><span class="no">Provider</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">current_user</span><span class="o">.</span><span class="n">shop</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>
</span><span class='line'> <span class="c1">#response.headers = @oauth2.response_headers</span>
</span><span class='line'> <span class="c1">#response.status = @oauth2.response_status</span>
</span><span class='line'> <span class="n">redirect_to</span> <span class="vi">@oauth2</span><span class="o">.</span><span class="n">redirect_uri</span> <span class="ow">and</span> <span class="k">return</span> <span class="k">if</span> <span class="vi">@oauth2</span><span class="o">.</span><span class="n">redirect?</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">access_token</span> <span class="c1"># 返回access_token,记得返回值需为json</span>
</span><span class='line'> <span class="vi">@oauth2</span> <span class="o">=</span> <span class="no">OAuth2</span><span class="o">::</span><span class="no">Provider</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="kp">nil</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>
</span><span class='line'> <span class="n">render</span> <span class="n">json</span><span class="p">:</span> <span class="vi">@oauth2</span><span class="o">.</span><span class="n">response_body</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">allow</span> <span class="c1">#用户授权</span>
</span><span class='line'> <span class="vi">@auth</span> <span class="o">=</span> <span class="no">OAuth2</span><span class="o">::</span><span class="no">Provider</span><span class="o">::</span><span class="no">Authorization</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">current_user</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>
</span><span class='line'> <span class="k">if</span> <span class="n">params</span><span class="o">[</span><span class="s1">&#39;allow&#39;</span><span class="o">]</span> <span class="o">==</span> <span class="s1">&#39;1&#39;</span>
</span><span class='line'> <span class="vi">@auth</span><span class="o">.</span><span class="n">grant_access!</span>
</span><span class='line'> <span class="k">else</span>
</span><span class='line'> <span class="vi">@auth</span><span class="o">.</span><span class="n">deny_access!</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'> <span class="n">redirect_to</span> <span class="vi">@auth</span><span class="o">.</span><span class="n">redirect_uri</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>在config/routes.rb中添加下面路由</p>
<figure class='code'><figcaption><span>config/routes.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="n">get</span> <span class="s1">&#39;/oauth/authorize&#39;</span> <span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="s1">&#39;oauth#authorize&#39;</span> <span class="p">,</span> <span class="n">as</span><span class="p">:</span> <span class="ss">:authorize</span>
</span><span class='line'> <span class="n">post</span> <span class="s1">&#39;/oauth/access_token&#39;</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="s1">&#39;oauth#access_token&#39;</span><span class="p">,</span> <span class="n">as</span><span class="p">:</span> <span class="ss">:access_token</span>
</span><span class='line'> <span class="n">match</span> <span class="s1">&#39;/oauth/allow&#39;</span> <span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="s1">&#39;oauth#allow&#39;</span> <span class="p">,</span> <span class="n">as</span><span class="p">:</span> <span class="ss">:oauth_allow</span>
</span></code></pre></td></tr></table></div></figure>
<p>现在来说,基本流程就定义清楚了。</p>
<p>这时用户已经能通过如下方式请求授权了</p>
<figure class='code'><figcaption><span>client_demo.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;oauth2&#39;</span>
</span><span class='line'><span class="n">client</span> <span class="o">=</span> <span class="no">OAuth2</span><span class="o">::</span><span class="no">Client</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;client_id&#39;</span><span class="p">,</span> <span class="s1">&#39;client_secret&#39;</span><span class="p">,</span> <span class="ss">:site</span> <span class="o">=&gt;</span> <span class="s1">&#39;https://example.org&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">client</span><span class="o">.</span><span class="n">auth_code</span><span class="o">.</span><span class="n">authorize_url</span><span class="p">(</span><span class="ss">:redirect_uri</span> <span class="o">=&gt;</span> <span class="s1">&#39;http://localhost:8080/oauth2/callback&#39;</span><span class="p">)</span>
</span><span class='line'><span class="c1"># =&gt; &quot;https://example.org/oauth/authorization?response_type=code&amp;client_id=client_id&amp;redirect_uri=http://localhost:8080/oauth2/callback&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="n">token</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">auth_code</span><span class="o">.</span><span class="n">get_token</span><span class="p">(</span><span class="s1">&#39;authorization_code_value&#39;</span><span class="p">,</span> <span class="ss">:redirect_uri</span> <span class="o">=&gt;</span> <span class="s1">&#39;http://localhost:8080/oauth2/callback&#39;</span><span class="p">)</span>
</span><span class='line'><span class="n">response</span> <span class="o">=</span> <span class="n">token</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;/api/resource&#39;</span><span class="p">,</span> <span class="ss">:params</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="s1">&#39;query_foo&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;bar&#39;</span> <span class="p">})</span>
</span><span class='line'><span class="n">response</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">name</span>
</span><span class='line'><span class="c1"># =&gt; OAuth2::Response</span>
</span></code></pre></td></tr></table></div></figure>
<h3>过滤器</h3>
<p>当然,这里在我们服务器上得加个过滤器,去验证用户是否是正确的。</p>
<figure class='code'><figcaption><span>application_controller.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="k">def</span> <span class="nf">login_or_oauth_required</span>
</span><span class='line'> <span class="k">unless</span> <span class="n">session</span><span class="o">[</span><span class="ss">:shop</span><span class="o">]</span>
</span><span class='line'> <span class="n">token</span> <span class="o">=</span> <span class="no">OAuth2</span><span class="o">::</span><span class="no">Provider</span><span class="o">.</span><span class="n">access_token</span><span class="p">(</span><span class="kp">nil</span><span class="p">,</span> <span class="o">[]</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>
</span><span class='line'> <span class="k">unless</span> <span class="n">token</span><span class="o">.</span><span class="n">valid?</span>
</span><span class='line'> <span class="n">render</span> <span class="n">json</span><span class="p">:</span> <span class="p">{</span><span class="n">error</span><span class="p">:</span> <span class="s1">&#39;[API] Invalid API key or permission token (unrecognized login or wrong password)&#39;</span><span class="p">}</span>
</span><span class='line'> <span class="k">else</span>
</span><span class='line'> <span class="n">session</span><span class="o">[</span><span class="ss">:shop</span><span class="o">]</span> <span class="o">||=</span> <span class="n">token</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">as_json</span><span class="p">(</span><span class="n">only</span><span class="p">:</span> <span class="o">[</span><span class="ss">:deadline</span><span class="p">,</span> <span class="ss">:created_at</span><span class="p">,</span> <span class="ss">:updated_at</span><span class="p">,</span> <span class="ss">:name</span><span class="o">]</span><span class="p">)</span><span class="o">[</span><span class="s1">&#39;shop&#39;</span><span class="o">]</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<h3>参考资料</h3>
<p><a href="http://developer.github.com/v3/oauth/">github-oauth2</a>
<a href="http://wenku.baidu.com/view/b37ed7260722192e4536f66e.html">oauth2中文</a>
<a href="http://oauth.net/2/">oauth2-spec</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2011/09/28/introduce-active-admin-framework/">后台管理框架active_admin</a></h1>
<p class="meta">
<time datetime="2011-09-28T00:00:00+08:00" pubdate data-updated="true">Sep 28<span>th</span>, 2011</time>
</p>
</header>
<div class="entry-content"><h2>简介</h2>
<p>基于rails的管理框架还是很多的,例如,rails_admin, active_admin等。
这里,介绍下最近使用的 <a href="https://github.com/gregbell/active_admin">active_admin</a></p>
<h2>安装</h2>
<p>在gemfile中添加</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'> gem <span class="s1">&#39;activeadmin&#39;</span>
</span><span class='line'> gem <span class="s1">&#39;sass-rails&#39;</span> <span class="c">#only in rails 3.1</span>
</span></code></pre></td></tr></table></div></figure>
<p>装完对应的gem之后,执行下面task</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'> rails generate active_admin:install
</span></code></pre></td></tr></table></div></figure>
<p>这里会创建对应的文件,主要是在routes中添加对应的路由,和active_admin的设置文件,还有,就是
创建了对应的active_admin model,和对应的database migrate,在migrate中,创建了初始化的active_admin
的记录admin@example.com,我们可以通过这个登录后台管理的页面。当然,在执行数据迁徙前,我们可以将
这个改成我们所希望创建的默认用户。</p>
<h2>使用</h2>
<p>active_admin 创建的文件都放在app/admin这个目录下面。我们要想自定义首页显示的内容,可以查看dashboard文件,
更改里面的内容就能直观的显示在首页上了。 如果,我们原来使用的控制器,定义了module Admin里,我们可以通过更改
config/initializers/active_admin.rb这里面的配置,将config.default_namespace = :admin,换成我们所想要的,防止冲突。</p>
<p>当我们要对某个表进行管理时,我们此时就可以通过创建对应的active_admin resource,执行下面命令,就可以创建对应的ActiveAdmin model了.
执行完这个之后,在我们的后台中,会自动创建对应的增删改查功能。同样,我们可以自定义显示它,具体可以查看 <a href="http://activeadmin.info/docs/3-index-pages/index-as-table.html">资料</a></p>
<h2>参考资料</h2>
<p><a href="https://github.com/gregbell/active_admin.git">github gem</a>
<a href="http://demo.activeadmin.info/admin">demo</a>
<a href="http://rubydoc.info/github/gregbell/active_admin/master/frames">doc</a>
<a href="http://activeadmin.info/">info</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2011/08/29/how-to-update-rails-project-to-rails-3.1/">将rails项目升级到rails 3.1</a></h1>
<p class="meta">
<time datetime="2011-08-29T00:00:00+08:00" pubdate data-updated="true">Aug 29<span>th</span>, 2011</time>
</p>
</header>
<div class="entry-content"><p>有很久都没更新博客了,最近,发现很多东西不记下来,特别容易忘记。最近把项目从rails 3.0迁移
到了3.1版本,rails 3.1增加了许多新的特性,比如说:默认支持coffee-script,把jQuery作为默认的js库
等等,还有一些新特性,可以查看 <a href="http://guides.rubyonrails.org/3_1_release_notes.html">rails 3.1 release note</a> .</p>
<h2>更新gem</h2>
<p>比如说把原来的meta_where替换成squeel等等,基本上,现在版本的gem都支持rails 3.1了, 另外,原来的用于编译
coffeescript的barista可以去掉了,因为默认rails模版已经支持编译coffeescript了。以前,默认的情况下,我们设置
base=true这个配置,用来不让</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="p">...</span>
</span><span class='line'> <span class="p">}).</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>包围js代码,这样很多js变量就能全局性的用了。但是,现在rails ,默认是将bare设置为false的,这个可以看 <a href="https://github.com/rails/rails/issues/1125">rails的源码</a> .在这种情况下,我们可以通过设置gloabla 变量,如window.xxx = xxx .
这里有 <a href="http://stackoverflow.com/questions/5211638/pattern-for-coffeescript-modules/5212449#5212449">一些讨论</a> ,
另外还有就是active_hash这个gem也做了一些改变, 当我们要实现activerecord和activehash对象关联时,得将原来的代码改写成:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Country</span> <span class="o">&lt;</span> <span class="no">ActiveHash</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Person</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'> <span class="kp">extend</span> <span class="no">ActiveHash</span><span class="o">::</span><span class="no">Associations</span><span class="o">::</span><span class="no">ActiveRecordExtensions</span>
</span><span class='line'> <span class="n">belongs_to_active_hash</span> <span class="ss">:country</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<h2>sprockets , asset pipline</h2>
<p>这个应该是rails 3.1最主要的更新内容了。用asset pipline 替换了原有的?形式的引入文件, 利用的是 <a href="https://github.com/sstephenson/sprockets">sprockets gem</a> .这个具体可以看 <a href="http://guides.rubyonrails.org/asset_pipeline.html">文章</a> ,这里面详细介绍了,用最新hash方式缓存静态文件。</p>
<h2>subdomain, domain</h2>
<p>现在rails url helper已经默认支持subdomain了,我们可以使用xxx_url(subdomian: xxx)</p>
<h2>Http Steaming</h2>
<p>HTTP Streaming是Rails 3.1中一项新改进,可以让浏览器在页面作出响应的同时下载样式表和JavaScript文件。该特性需要Ruby 1.9.2,以及Web服务器的支持,幸运的是流行的nginx和unicorn组合已经支持。</p>
<h2>一些方法</h2>
<p>在rails 3.1 的更新日志中,你会发现,clone方法发生了改变,我们以前用clone方法复制model,会是以下这种情况</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="nb">p</span> <span class="o">=</span> <span class="no">Product</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">clone</span>
</span><span class='line'> <span class="nb">p</span><span class="o">.</span><span class="n">new_record?</span> <span class="c1"># =&gt; true</span>
</span></code></pre></td></tr></table></div></figure>
<p>而现在clone 之后的对象调用new_record?会返回false,即这是一种浅赋值,以下是changelog内容</p>
<pre>
1. ActiveRecord::Base#dup and ActiveRecord::Base#clone semantics have changed to closer match normal Ruby dup and clone semantics.
1. Calling ActiveRecord::Base#clone will result in a shallow copy of the record, including copying the frozen state. No callbacks will be called.
1. Calling ActiveRecord::Base#dup will duplicate the record, including calling after initialize hooks. Frozen state will not be copied, and all associations will be cleared. A duped record will return true for new_record?, have a nil id field, and is saveable.
</pre>
<p>另外,现在在query的时候,我们不能写以前的那种关联方式查询了,例如下面例子</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="no">Shop</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">user</span><span class="p">:</span> <span class="no">User</span><span class="o">.</span><span class="n">first</span><span class="p">)</span>
</span><span class='line'> <span class="c1">#上面的话得换成</span>
</span><span class='line'> <span class="no">Shop</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">user_id</span><span class="p">:</span> <span class="no">User</span><span class="o">.</span><span class="n">first</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>
<p>还有,现在通过association.new创建对象,等于以前的build方式创建对象了。</p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2011/06/12/rails3-email-setup/">Rails3中邮件服务设置</a></h1>
<p class="meta">
<time datetime="2011-06-12T00:00:00+08:00" pubdate data-updated="true">Jun 12<span>th</span>, 2011</time>
</p>
</header>
<div class="entry-content"><p>对于一个web服务,邮件提醒是必须的,比如,发送给用户注册信息,密码重置信息等等,
都需要通过邮件来提醒用户。这里简单介绍一下rails3的邮件服务设置。</p>
<p>首先,我们得创建mailer</p>
<div>
<pre>
<code class='bash'>rails g mailer UserMailer</code>
</pre>
</div>
<p>接着,我们编辑app/mailer/user_mailer</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">UserMailer</span> <span class="o">&lt;</span> <span class="no">ActionMailer</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'> <span class="n">default</span> <span class="ss">:from</span> <span class="o">=&gt;</span> <span class="s2">&quot;xxx@gmail.com&quot;</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">welcome</span>
</span><span class='line'> <span class="n">mail</span><span class="p">(</span><span class="n">to</span><span class="p">:</span> <span class="s2">&quot;xxx@gmail.com&quot;</span><span class="p">,</span><span class="n">body</span><span class="ss">:&quot;aaa&quot;</span><span class="p">,</span> <span class="n">subject</span><span class="p">:</span> <span class="s2">&quot;welcome&quot;</span><span class="p">)</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>下一步,就是配置action mailer了,由于国内的gmail连接老出现问题,所以这里就介绍163的了,
基本都差不多</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="no">ActionMailer</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">smtp_settings</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'> <span class="ss">:address</span> <span class="o">=&gt;</span> <span class="s2">&quot;smtp.163.com&quot;</span><span class="p">,</span>
</span><span class='line'> <span class="ss">:port</span> <span class="o">=&gt;</span> <span class="mi">25</span><span class="p">,</span>
</span><span class='line'> <span class="ss">:domain</span> <span class="o">=&gt;</span> <span class="s2">&quot;domail.com&quot;</span><span class="p">,</span>
</span><span class='line'> <span class="ss">:user_name</span> <span class="o">=&gt;</span> <span class="s2">&quot;xxx@163.com&quot;</span><span class="p">,</span>
</span><span class='line'> <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="s2">&quot;xxx&quot;</span>
</span><span class='line'> <span class="ss">:authentication</span> <span class="o">=&gt;</span> <span class="s2">&quot;plain&quot;</span><span class="p">,</span>
</span><span class='line'> <span class="c1">#if got the same error with me,please change the options false</span>
</span><span class='line'> <span class="ss">:enable_starttls_auto</span> <span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="no">ActionMailer</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">default_url_options</span><span class="o">[</span><span class="ss">:host</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;localhost:3000&quot;</span>
</span></code></pre></td></tr></table></div></figure>
<p>注意:如果你和我出现了同样的<a href="https://gist.github.com/1021285">堆栈错误</a></p>
<p>这样,我们在rails console中执行 UserMailer.welcome.deliver就能发送邮件到指定的
邮箱了。</p>
<h2>参考资料</h2>
<p><a href="http://guides.rubyonrails.org/action_mailer_basics.html">mail guides</a>
<a href="http://asciicasts.com/episodes/206-action-mailer-in-rails-3">action mailer in rails 3</a></p>
</div>
</article>
<div class="pagination">
<a class="prev" href="/blog/page/2/">&larr; Older</a>
<a href="/blog/archives">Blog Archives</a>
</div>
</div>
<aside class="sidebar">
<section>
<h1>Recent Posts</h1>
<ul id="recent_posts">
<li class="post">
<a href="/blog/2012/01/18/create-blog-with-nodejs/">用NodeJS创建博客</a>
</li>
<li class="post">
<a href="/blog/2012/01/09/how-to-add-image-to-map-pin/">给地图大头针加图片</a>
</li>
<li class="post">
<a href="/blog/2012/01/08/how-to-build-cocoa2d-application/">构建cocos2d开发环境</a>
</li>
<li class="post">
<a href="/blog/2012/01/06/introduct-ui-gesture-recognizer/">IOS手势操作</a>
</li>
<li class="post">
<a href="/blog/2012/01/06/how-to-draw-circle/">how-to-draw-circle</a>
</li>
</ul>
</section>
<section>
<h1>About Me</h1>
<ul id="about_me">
<li class="post">
I am a developer using Ruby,Java and obj-c!
</li>
<li class="post">
<a href="http://about.me/weihuilee">About Me</a>
</li>
<li class="post">
<a href="http://github.com/liwh">Github</a>
</li>
<li class="post">
<a href="http://twitter.com/weihuilee">Twitter</a>
</li>
</ul>
</section>
</aside>
</div>
</div>
<footer role="contentinfo"><p>
Copyright &copy; 2012 - liwh -
<span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>
</p>
</footer>
<script type="text/javascript">
var disqus_shortname = 'liwh87';
var disqus_script = 'count.js';
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}());
</script>
<script type="text/javascript">
(function(){
var twitterWidgets = document.createElement('script');
twitterWidgets.type = 'text/javascript';
twitterWidgets.async = true;
twitterWidgets.src = 'http://platform.twitter.com/widgets.js';
document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
})();
</script>
</body>
</html>