Coder X
Stay hungry,Stay foolish.
2016-10-19T11:46:59.000Z
http://www.xayoung.cn/
xayoung
Hexo
Hybrid App(二):Cordova插件开发
http://www.xayoung.cn/2016/09/20/Hybrid App(二):Cordova插件开发/
2016-09-20T09:50:44.000Z
2016-10-19T11:46:59.000Z
<p>上一章已经将Cordova集成进我们的项目中去了,下面我们创建插件来扩展使用场景。</p>
<h2 id="创建Plugin插件"><a href="#创建Plugin插件" class="headerlink" title="创建Plugin插件"></a>创建Plugin插件</h2><ul>
<li>新建文件夹Plugins,并添加进项目中<br><img src="http://ww3.sinaimg.cn/large/5e999b55gw1f8xowkt5uij20cy090mxv.jpg" alt="此处输入图片的描述"></li>
<li>在Plugins中,commend + N 新建继承CDVPlugin的TestPlugin插件 <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">.h</span><br><span class="line">#import <Cordova/CDV.h></span><br><span class="line"></span><br><span class="line">@interface TestPlugin : CDVPlugin</span><br><span class="line"></span><br><span class="line">- (void)test:(CDVInvokedUrlCommand*)command;</span><br><span class="line"></span><br><span class="line">@end</span><br></pre></td></tr></table></figure>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">.m</span><br><span class="line">#import "TestPlugin.h"</span><br><span class="line">#import <Cordova/CDV.h></span><br><span class="line"></span><br><span class="line">@implementation TestPlugin{</span><br><span class="line">NetWorkManager *manager;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (void)test:(CDVInvokedUrlCommand*)command</span><br><span class="line">{</span><br><span class="line">DLog(@"%@",command.arguments);</span><br><span class="line">manager = [NetWorkManager sharedNetWorkManager];</span><br><span class="line">[self loadNewData:command];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">- (void) loadNewData:(CDVInvokedUrlCommand*)command</span><br><span class="line">{ //网络请求,将传递过来的第一个参数作为网络请求的参数</span><br><span class="line">[manager networkHealthInfoAll:command.arguments[0] ...</span><br><span class="line"></span><br><span class="line">CDVPluginResult* pluginResult = nil;</span><br><span class="line">//要传递回去的参数,responDict为网络请求回来的数据</span><br><span class="line">NSDictionary * ret = @{@"success":@"1",@"message":@"参数不为空",@"code":@(200),@"data":responDict};</span><br><span class="line"></span><br><span class="line">pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:ret];</span><br><span class="line"></span><br><span class="line">[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">@end</span><br></pre></td></tr></table></figure>
<h2 id="写入配置文件"><a href="#写入配置文件" class="headerlink" title="写入配置文件"></a>写入配置文件</h2><ul>
<li>打开文件夹下的config.xml文件,在widget标签下输入:<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><feature name="TestPlugin"></span><br><span class="line"><param name="ios-package" value="TestPlugin" /></span><br><span class="line"></feature></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>此时Cordova可以找到插件,完成JavaScript和Objective C的桥接,现在可以使用JavaScript来调用TestPlugin插件了</p>
<h2 id="调用插件"><a href="#调用插件" class="headerlink" title="调用插件"></a>调用插件</h2><ul>
<li>打开js文件,进行调用<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">btn.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"></span><br><span class="line"><span class="comment">//test plugin</span></span><br><span class="line">cordova.exec(<span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{</span><br><span class="line"><span class="comment">//成功的回调函数</span></span><br><span class="line">alert(msg.data.newsTitles[<span class="number">0</span>].healthInfoTitle);</span><br><span class="line">},</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"><span class="comment">//失败的回调函数</span></span><br><span class="line">},</span><br><span class="line"><span class="string">"TestPlugin"</span>,<span class="comment">//插件名</span></span><br><span class="line"><span class="string">"test"</span>,</span><br><span class="line">[<span class="string">"行业动态"</span>]);<span class="comment">//需要传递至native的参数</span></span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>至此一个简易的插件就完成了,后续可根据项目业务需求进行开发。</p>
<p><img src="http://ww1.sinaimg.cn/large/5e999b55gw1f8xp95ov6gg208q0fo0ym.gif" alt="此处输入图片的描述"></p>
<p>上一章已经将Cordova集成进我们的项目中去了,下面我们创建插件来扩展使用场景。</p>
<h2 id="创建Plugin插件"><a href="#创建Plugin插件" class="headerlink" title="创建Plugin插件"></a>创建Plugi
Hybrid App(一):Cordova集成
http://www.xayoung.cn/2016/09/03/Hybrid App(一):Cordova集成/
2016-09-03T06:50:44.000Z
2016-10-19T11:47:04.000Z
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>项目技术预研Hybrid相关技术,查阅资料实践后记录下Cordova集成的过程。</p>
<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>Cordova: <a href="http://cordova.apache.org/" target="_blank" rel="external">http://cordova.apache.org/</a></p>
<blockquote>
<p>Apache Cordova is an open-source mobile development framework. It allows you to use standard web technologies such as HTML5, CSS3, and JavaScript for cross-platform development, avoiding each mobile platforms’ native development language. Applications execute within wrappers targeted to each platform, and rely on standards-compliant API bindings to access each device’s sensors, data, and network status.<br>Use Apache Cordova if you are: a mobile developer interested in mixing native application components with aWebView(special browser window) that can access device-level APIs, or if you want to develop a plugin interface between native and WebView components.</p>
</blockquote>
<p>大意:Cordova 是开源的移动开发框架。可以使用标准的WEB技术进行跨平台的开发,避免了不同移动平台不同的开发语言重复边写。把能访问设备级 API 的 WebView 集成到 Native 应用中,或通过开发接口插件实现 navtive 和 WebView 组件之间的交互。在启用Cordova的WebView中,为应用提供了完整的用户接口。在某些平台中也可以作为一个嵌入在本地native应用的组件。</p>
<h2 id="环境-amp-创建"><a href="#环境-amp-创建" class="headerlink" title="环境&创建"></a>环境&创建</h2><ul>
<li>安装Node.js </li>
</ul>
<p><a href="https://nodejs.org/en/download/" target="_blank" rel="external">https://nodejs.org/en/download/</a></p>
<ul>
<li><p>终端输入如下命令 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo npm install –g cordova</span><br></pre></td></tr></table></figure>
</li>
<li><p>建立cordova项目</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ cd Desktop/</span><br><span class="line">$ cordova create CordovaDemo</span><br></pre></td></tr></table></figure>
</li>
<li><p>加入iOS项目</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ cd CordovaDemo/</span><br><span class="line">$ cordova platform add ios</span><br><span class="line"></span><br><span class="line">Adding ios project...</span><br><span class="line">Creating Cordova project for the iOS platform:</span><br><span class="line">Path: platforms/ios</span><br><span class="line">Package: io.cordova.hellocordova</span><br><span class="line">Name: HelloCordova</span><br><span class="line">iOS project created with cordova-ios@4.2.1</span><br><span class="line">Discovered plugin "cordova-plugin-whitelist" in config.xml. Adding it to the project</span><br><span class="line">Fetching plugin "cordova-plugin-whitelist@1" via npm</span><br><span class="line">Installing "cordova-plugin-whitelist" for ios</span><br></pre></td></tr></table></figure>
</li>
<li><p>显示已经安装的平台项目以及可安装的平台</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$ cordova platform ls </span><br><span class="line">Installed platforms:</span><br><span class="line">ios 4.2.1</span><br><span class="line">Available platforms: </span><br><span class="line">amazon-fireos ~3.6.3 (deprecated)</span><br><span class="line">android ~5.2.0</span><br><span class="line">blackberry10 ~3.8.0</span><br><span class="line">browser ~4.1.0</span><br><span class="line">firefoxos ~3.6.3</span><br><span class="line">osx ~4.0.1</span><br><span class="line">webos ~3.7.0</span><br></pre></td></tr></table></figure>
</li>
<li><p>build iOS项目</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ cordova build ios</span><br><span class="line"></span><br><span class="line">Building project: /Users/xjy/Desktop/test/Demo/platforms/ios/HelloCordova.xcodeproj</span><br><span class="line">Configuration: Debug</span><br><span class="line">Platform: emulator</span><br><span class="line">Build settings from command line:</span><br><span class="line">......</span><br></pre></td></tr></table></figure>
</li>
<li><p>Xcode 打开项目运行<br><img src="http://upload-images.jianshu.io/upload_images/965192-6f989b735372c194.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="此处输入图片的描述"></p>
</li>
</ul>
<h2 id="已有的Native项目中加入Cordova"><a href="#已有的Native项目中加入Cordova" class="headerlink" title="已有的Native项目中加入Cordova"></a>已有的Native项目中加入Cordova</h2><ul>
<li><p>拷贝Cordova相关文件(路径:cordovaDemo/platforms/ios)到House目录下,拷贝后目录结构如下<br>-<img src="http://ww1.sinaimg.cn/large/5e999b55gw1f8xm8x36y5j20bc0aeaau.jpg" alt="此处输入图片的描述"></p>
</li>
<li><p>CordovaLib.xcodeproj添加到House工程中,右键选择Add Files To House</p>
</li>
<li><p>添加www目录到工程中,记得是勾选Create folder references</p>
</li>
<li><p>config.xml添加到Demo工程中,右键选择Add Files To Demo(路径:cordovaDemo/platforms/ios/CordovaDemo/config.xml )</p>
</li>
<li><p>Build Settings->Other Links, 设置-Objc -all_load</p>
</li>
<li><p>Build Phases->Target Dependencies添加CordovaLib</p>
</li>
<li><p>Link Binary With Librarys添加libCordova.a, MobileCoreServices,AssetsLibrary</p>
</li>
<li><p>command + B编译通过</p>
</li>
<li><p>www文件夹放入对应的文件</p>
</li>
<li><p>调用CDVViewController</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">#import <Cordova/CDVViewController.h></span><br><span class="line"></span><br><span class="line">//action</span><br><span class="line">CDVViewController* vc = [CDVViewController new];</span><br><span class="line">vc.hidesBottomBarWhenPushed = YES;</span><br><span class="line">[self.navigationController pushViewController:vc animated:YES];</span><br></pre></td></tr></table></figure>
<p>下一章记录一下插件开发的相关流程</p>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>项目技术预研Hybrid相关技术,查阅资料实践后记录下Cordova集成的过程。</p>
<h2 id="概述"><a href="#概述"
LoveqSwift(二):个人项目《一些事一些情》iOS客户端 简介 & BUG & 建议
http://www.xayoung.cn/2016/06/25/LoveqSwift(二):LoveQ——个人项目《一些事一些情》第三方APP/
2016-06-25T02:30:21.000Z
2016-07-11T13:29:28.000Z
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>上一篇博文已经描述了怎么拿到所有节目的信息,这里简单总结下使用Swift语言写LoveQ iOS客户端的基本框架,有BUG和建议可以在评论中指出。<br><img src="http://ww3.sinaimg.cn/large/5e999b55gw1f57gs1777sj20hs0vkq5i.jpg" alt="此处输入图片的描述"></p>
<hr>
<h1 id="界面"><a href="#界面" class="headerlink" title="界面"></a>界面</h1><p>LoveQ使用了<a href="https://github.com/sascha/DrawerController" target="_blank" rel="external">DrawerController</a>这款第三方控件作为主框架,centerViewController为音乐播放器,左划弹出的rightViewController为下载完成的节目列表,右话弹出的leftViewController为菜单页,可以跳转到其他ViewController,轻量级,不进行多次跳转等深层级操作即可实现大部分页面的跳转。<br><img src="http://ww4.sinaimg.cn/large/006tNbRwgw1f5qafv8akqj30ku112q4u.jpg" alt="此处输入图片的描述"></p>
<p>音乐播放器页面采用了水波纹的动态效果<br><img src="http://ww3.sinaimg.cn/large/006tNbRwgw1f5qagwip8ij30ku112414.jpg" alt="此处输入图片的描述"></p>
<p>节目列表设置了cell的渐变色<br><img src="http://ww1.sinaimg.cn/large/5e999b55gw1f57gig2u59j20ku112jty.jpg" alt="此处输入图片的描述"></p>
<hr>
<h1 id="后台"><a href="#后台" class="headerlink" title="后台"></a>后台</h1><p>使用<a href="https://www.wilddog.com" target="_blank" rel="external">wilddong</a>作为数据存储,闪电上手<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> ref = <span class="type">Wilddog</span>(url: <span class="type">LoveqConfig</span>.<span class="type">WilddogURL</span> + <span class="string">"index/programIndex"</span>)</span><br><span class="line">ref.observeEventType(.<span class="type">Value</span>, withBlock: { snapshot <span class="keyword">in</span></span><br><span class="line">...</span><br></pre></td></tr></table></figure></p>
<h2 id=""><a href="#" class="headerlink" title=""></a><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f57gnx1mv7j20kv0didgh.jpg" alt="此处输入图片的描述"></h2><h1 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h1><p>采用信鸽推送实现更新通知,3D Touch实现快速进入、分享,使用<a href="https://github.com/nixzhu/MonkeyKing" target="_blank" rel="external">MonkeyKing</a>实现分享到微信/朋友圈,更多的详见APP。</p>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>上一篇博文已经描述了怎么拿到所有节目的信息,这里简单总结下使用Swift语言写LoveQ iOS客户端的基本框架,有BUG和建议可以在评论中
LoveqSwift(一):Python爬虫抓取loveq.cn所有节目信息
http://www.xayoung.cn/2016/05/26/LoveqSwift(一):Python爬虫抓取loveq.cn所有节目信息/
2016-05-26T13:04:30.000Z
2016-05-26T14:21:28.000Z
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>听《<a href="http://www.loveq.cn/" target="_blank" rel="external">一些事一些情</a>》已经十多年,近来通勤时间重温以往节目的时候发现,无论官方或民间的APP都或多或少有些遗憾,虽然也是个重复造轮子的活,但是自己动手写一个或许会更有乐趣呢。</p>
<hr>
<h1 id="缘由"><a href="#缘由" class="headerlink" title="缘由"></a>缘由</h1><p>首先,开发一款音乐播放器的移动APP,我们得有api才可以展示数据,下载音频文件,最终播放节目。如何获取到每一期节目的数据呢?</p>
<ul>
<li>方案一<br>通过对现有的APP抓包,这个方案最简单快捷,使用charles之类的工具可以对官方和民间APP进行抓包,获取api。但,选取的几款APP均不是采用get、post请求的,没办法轻易拿到数据,pass。</li>
<li>方案二<br>通过APP内部加载单页web,获取网页源代码后,通过正则表达式提取节目信息以及下载链接并展示。但,经过测试后发现,此方案会有比较严重的性能问题,加载时间过久,用户体验较差,pass。(以下为两种加载web方式的测试代码)</li>
</ul>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//下标截取,蠢方法一</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">subWebstring</span><span class="params">(HTMLSource: [String?])</span></span> -> <span class="type">Array</span><<span class="type">AnyObject</span>> {</span><br><span class="line"><span class="keyword">let</span> reg = <span class="keyword">try</span>! <span class="type">NSRegularExpression</span>.<span class="keyword">init</span>(pattern: parten, options: .<span class="type">CaseInsensitive</span>)</span><br><span class="line"><span class="keyword">let</span> <span class="type">HTML</span> = <span class="type">HTMLSource</span>[<span class="number">0</span>]! <span class="keyword">as</span> <span class="type">NSString</span></span><br><span class="line"><span class="keyword">let</span> array0 = <span class="type">HTML</span>.componentsSeparatedByString(<span class="string">"节目名称</dt>"</span>)</span><br><span class="line"><span class="keyword">let</span> <span class="type">HTML2</span> = array0[<span class="number">1</span>] <span class="keyword">as</span> <span class="type">NSString</span></span><br><span class="line"><span class="keyword">let</span> array = reg.matchesInString(<span class="type">HTML2</span> <span class="keyword">as</span> <span class="type">String</span>, options: .<span class="type">ReportCompletion</span>, range: <span class="type">NSMakeRange</span>(<span class="number">0</span>, <span class="type">HTML2</span>.length))</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> data = <span class="type">Array</span><<span class="type">AnyObject</span>>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> match: <span class="type">NSTextCheckingResult</span> <span class="keyword">in</span> array {</span><br><span class="line"><span class="keyword">let</span> range = match.range</span><br><span class="line"><span class="keyword">let</span> string: <span class="type">String</span> = <span class="type">HTML2</span>.substringWithRange(range)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> s1 = (string <span class="keyword">as</span> <span class="type">NSString</span>).substringWithRange(<span class="type">NSMakeRange</span>(<span class="number">9</span>, <span class="number">26</span>))</span><br><span class="line"><span class="keyword">let</span> s2 = (string <span class="keyword">as</span> <span class="type">NSString</span>).substringWithRange(<span class="type">NSMakeRange</span>(<span class="number">173</span>, <span class="number">13</span>))</span><br><span class="line"><span class="keyword">let</span> s3 = (string <span class="keyword">as</span> <span class="type">NSString</span>).substringWithRange(<span class="type">NSMakeRange</span>(<span class="number">167</span>, <span class="number">5</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> ns3 = [<span class="string">"url"</span>:s1, <span class="string">"title"</span>:s2, <span class="string">"format"</span>:s3]</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> user = <span class="type">Mapper</span><<span class="type">ProgrammerListModel</span>>().<span class="built_in">map</span>(ns3)</span><br><span class="line">data.append(user!)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> data</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用第三方框架Fuzi</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Fuzi</span><span class="params">(HTMLSource: [String?])</span></span>{</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> html = <span class="type">HTMLSource</span>[<span class="number">0</span>]!</span><br><span class="line"><span class="keyword">let</span> program = <span class="string">"program_download"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">do</span>{</span><br><span class="line"><span class="keyword">let</span> doc = <span class="keyword">try</span>! <span class="type">HTMLDocument</span>(string: html, encoding: <span class="type">NSUTF8StringEncoding</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> link <span class="keyword">in</span> doc.css(<span class="string">"a, link"</span>) {</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> str: <span class="type">String</span>? = link[<span class="string">"href"</span>]</span><br><span class="line"><span class="keyword">if</span> str != <span class="literal">nil</span> && str!.containsString(program) {</span><br><span class="line"><span class="built_in">print</span>(link[<span class="string">"href"</span>])</span><br><span class="line"><span class="keyword">if</span> !urlSource.<span class="built_in">contains</span>(str!) {</span><br><span class="line"><span class="keyword">if</span> str!.hasPrefix(program) {</span><br><span class="line">urlSource.append(str!)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(urlSource)</span><br><span class="line"><span class="keyword">for</span> link <span class="keyword">in</span> doc.css(<span class="string">"span"</span>) {</span><br><span class="line"><span class="keyword">let</span> s = link.stringValue <span class="keyword">as</span> <span class="type">NSString</span></span><br><span class="line"><span class="keyword">if</span> s.length > <span class="number">0</span> {</span><br><span class="line"><span class="keyword">let</span> s1 = (s <span class="keyword">as</span> <span class="type">NSString</span>).substringToIndex(<span class="number">1</span>)</span><br><span class="line"><span class="keyword">if</span> s1 == <span class="string">"【"</span> {</span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line">dataSource.append(s)</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">let</span> result = doc.eval(xpath: <span class="string">"count(/*/a)"</span>) {</span><br><span class="line"><span class="built_in">print</span>(<span class="string">"anchor count : \(result.doubleValue)"</span>)</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="built_in">print</span>(urlSource)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>方案三<br>通过抓取官网所有的节目信息和下载地址,自己搭建服务器提供api。此方案要实行对于个人来说有两个难点:1.怎么抓取一千多期节目的数据;2.怎么搭建服务器并提供接口。经过分析各种方案后,第一点可以通过Python爬虫解决,第二点,因后端知识树暂时没点,所以暂时使用实时云服务来替代。一开始是目标为<a href="https://www.firebase.com/" target="_blank" rel="external">firebase</a>,试用后发现,Google收购它后,慢慢添加Google一些服务接口进去了,由于众所周知的原因,最终选用了墙内的<a href="https://www.wilddog.com/" target="_blank" rel="external">wilddog</a>。</li>
</ul>
<hr>
<h1 id="动工"><a href="#动工" class="headerlink" title="动工"></a>动工</h1><p>方案选定后,正式动工。<br>Python为现学现卖,so,现阶段的目标实现需求达到目标即可。<br>经过分析网页源代码,抓取流程如下:<strong>在界面列表抓取当前页所有节目信息–>跳转单期节目的下载页获取真正的音频文件地址–>将节目信息与真正的音频文件地址并为字典按照月份分类再存入数组–>抓取下一页·····所有页抓取完毕后–>再按照年份进行分类–>分别写入不同的JSON文件</strong>。</p>
<p>需要用到的库:urllib2、re、json</p>
<h2 id="抓取界面信息"><a href="#抓取界面信息" class="headerlink" title="抓取界面信息"></a>抓取界面信息</h2><p>定义Class,初始化确定好下载页面的url,以及全局接收的数组</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Spider</span>:</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#初始化</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line">self.siteURL = <span class="string">'http://www.loveq.cn/program.php?&cat_id=20&'</span></span><br><span class="line">self.JSONMP3 = []</span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#获取索引页面的内容</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getPage</span><span class="params">(self,pageIndex)</span>:</span></span><br><span class="line">url = self.siteURL + <span class="string">"page="</span> + str(pageIndex)</span><br><span class="line">request = urllib2.Request(url)</span><br><span class="line">response = urllib2.urlopen(request)</span><br><span class="line"><span class="keyword">return</span> response.read().decode(<span class="string">'utf-8'</span>)</span><br></pre></td></tr></table></figure>
<h2 id="抓取当前页所有节目"><a href="#抓取当前页所有节目" class="headerlink" title="抓取当前页所有节目"></a>抓取当前页所有节目</h2><p>抓取完毕之后过滤掉WMA格式,并对粤语和普通话双版本进行分类</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#获取索引界面所有节目的信息</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getContents</span><span class="params">(self,pageIndex)</span>:</span></span><br><span class="line">page = self.getPage(pageIndex)</span><br><span class="line">pattern = re.compile(<span class="string">'<dl.*?clearfix">.*?<dt.*?<a.*?"(.*?)".*?target.*?">(.*?)</a>.*?class="ct"><span>(.*?)</dd>'</span>,re.S)</span><br><span class="line">items = re.findall(pattern,page)</span><br><span class="line"></span><br><span class="line">jsonChinese = []</span><br><span class="line">jsonMP3 = []</span><br><span class="line"><span class="keyword">for</span> item <span class="keyword">in</span> items:</span><br><span class="line">downloadURL = self.getDetailPage(item[<span class="number">0</span>])</span><br><span class="line"><span class="keyword">print</span> item</span><br><span class="line">name=item[<span class="number">2</span>].encode(<span class="string">"utf-8"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="string">'MP3格式'</span> <span class="keyword">in</span> name <span class="keyword">or</span> <span class="string">'mp3格式'</span> <span class="keyword">in</span> name:</span><br><span class="line"><span class="keyword">if</span> <span class="string">'普通话'</span> <span class="keyword">in</span> name:</span><br><span class="line"><span class="comment"># 保存普通话节目列表</span></span><br><span class="line">jsonChinese.append([downloadURL,item[<span class="number">1</span>],<span class="number">0</span>])</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line"><span class="comment">#保存粤语节目列表</span></span><br><span class="line">jsonMP3.append([downloadURL,item[<span class="number">1</span>],<span class="number">1</span>])</span><br><span class="line">contents = {}</span><br><span class="line">contents.setdefault(<span class="string">'url'</span>,downloadURL)</span><br><span class="line">contents.setdefault(<span class="string">'title'</span>,item[<span class="number">1</span>])</span><br><span class="line">contents.setdefault(<span class="string">'type'</span>,str(<span class="number">1</span>))</span><br><span class="line">self.JSONMP3.append(contents)</span><br><span class="line"><span class="comment">#2006-2009年的节目没有采用[MP3格式]xxxx这样的方式作为title,手动进行切换代码吧=.=</span></span><br><span class="line"><span class="comment"># jsonMP3.append([downloadURL, item[1], 1])</span></span><br><span class="line"><span class="comment"># contents = {}</span></span><br><span class="line"><span class="comment"># contents.setdefault('url', downloadURL)</span></span><br><span class="line"><span class="comment"># contents.setdefault('title', item[1])</span></span><br><span class="line"><span class="comment"># contents.setdefault('type', str(1))</span></span><br><span class="line"><span class="comment"># self.JSONMP3.append(contents)</span></span><br></pre></td></tr></table></figure>
<h2 id="跳转下载页面获取真正下载地址"><a href="#跳转下载页面获取真正下载地址" class="headerlink" title="跳转下载页面获取真正下载地址"></a>跳转下载页面获取真正下载地址</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#获取真实下载地址</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getDetailPage</span><span class="params">(self,infoURL)</span>:</span></span><br><span class="line">url = <span class="string">'http://www.loveq.cn/'</span> + infoURL</span><br><span class="line">response = urllib2.urlopen(url)</span><br><span class="line">content = response.read().decode(<span class="string">'utf-8'</span>)</span><br><span class="line">pattern = re.compile(<span class="string">'<div.*?more_downlink".*?style.*?<a.*?"(.*?)"'</span>,re.S)</span><br><span class="line">items = re.findall(pattern,content)</span><br><span class="line"><span class="keyword">for</span> item <span class="keyword">in</span> items:</span><br><span class="line">downloadURL = item</span><br><span class="line"><span class="keyword">return</span> downloadURL</span><br></pre></td></tr></table></figure>
<h2 id="分类保存所有节目数据"><a href="#分类保存所有节目数据" class="headerlink" title="分类保存所有节目数据"></a>分类保存所有节目数据</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#传入起止页码,获取界面json</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">savePagesInfo</span><span class="params">(self,start,end)</span>:</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(start,end+<span class="number">1</span>):</span><br><span class="line"><span class="keyword">print</span> <span class="string">u"looking for page"</span>,i</span><br><span class="line">self.savePageInfo(i)</span><br><span class="line"></span><br><span class="line"><span class="comment">#将整页节目列表保存起来</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">savePageInfo</span><span class="params">(self,pageIndex)</span>:</span></span><br><span class="line">self.getContents(pageIndex)</span><br></pre></td></tr></table></figure>
<h2 id="工具类"><a href="#工具类" class="headerlink" title="工具类"></a>工具类</h2><p>主要用于按照年份进行分类,并导出JSON文件</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Tools</span>:</span></span><br><span class="line"><span class="comment">#工具初始化</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line">self.JSONFile = {}</span><br><span class="line"></span><br><span class="line"><span class="comment">#传入起止月份,获取新json</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">saveNewJSONSInfo</span><span class="params">(self,year,start,end,JSON)</span>:</span></span><br><span class="line">self.JSONFile = {}</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(start,end+<span class="number">1</span>):</span><br><span class="line">self.saveJSONInfo(year,i,JSON)</span><br><span class="line"></span><br><span class="line"><span class="comment">#将节目保存起来</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">saveJSONInfo</span><span class="params">(self,year,Index,JSON)</span>:</span></span><br><span class="line">moonJSON = []</span><br><span class="line">moonstr = <span class="string">''</span></span><br><span class="line">moonstr2 = <span class="string">''</span></span><br><span class="line"><span class="keyword">if</span> Index < <span class="number">10</span>:</span><br><span class="line">moonstr = year + <span class="string">'.0'</span> + str(Index)</span><br><span class="line">moonstr2 = year + <span class="string">'0'</span> + str(Index)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">moonstr = year + <span class="string">'.'</span> + str(Index)</span><br><span class="line">moonstr2 = year + str(Index)</span><br><span class="line"><span class="keyword">for</span> item <span class="keyword">in</span> JSON:</span><br><span class="line"><span class="keyword">if</span> moonstr <span class="keyword">in</span> item[<span class="string">'title'</span>]:</span><br><span class="line">moonJSON.append(item)</span><br><span class="line">self.JSONFile.setdefault(moonstr2,moonJSON)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">store</span><span class="params">(self,year,JSON)</span>:</span></span><br><span class="line"><span class="keyword">with</span> open( year + <span class="string">'JSONFile.json'</span>, <span class="string">'w'</span>) <span class="keyword">as</span> f:</span><br><span class="line">f.write(json.dumps(JSON))</span><br></pre></td></tr></table></figure>
<h2 id="Let’s-go"><a href="#Let’s-go" class="headerlink" title="Let’s go"></a>Let’s go</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#传入起止页码即可,在此传入了1,71,表示抓取第2到10页的节目</span></span><br><span class="line">spider = Spider()</span><br><span class="line">spider.savePagesInfo(<span class="number">1</span>,<span class="number">71</span>)</span><br><span class="line">tool = Tools()</span><br><span class="line">totalJSON ={}</span><br><span class="line"><span class="comment">#设置年份,3代表2003年</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">3</span>,<span class="number">16</span>):</span><br><span class="line">year = <span class="string">''</span></span><br><span class="line"><span class="keyword">if</span> i < <span class="number">10</span> :</span><br><span class="line">year = <span class="string">'200'</span> + str(i)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">year = <span class="string">'20'</span> + str(i)</span><br><span class="line">tool.saveNewJSONSInfo(year,<span class="number">1</span>,<span class="number">12</span>,spider.JSONMP3)</span><br><span class="line">totalJSON.setdefault(year,tool.JSONFile)</span><br><span class="line"><span class="comment">#保存JSON文件到当前文件夹</span></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line">tool.store(year,totalJSON)</span><br></pre></td></tr></table></figure>
<p><img src="http://ww1.sinaimg.cn/large/5e999b55gw1f48xhpl4ang20kx0hvnil.gif" alt="此处输入图片的描述"><br>大功告成!然后将导出的JSON文件导入到wilddog。<br>接下来的工作就是整个APP,LoveqSwift项目的构建了。<br>最后附上github:<a href="http://t.cn/R5AVbTH" target="_blank" rel="external">http://t.cn/R5AVbTH</a></p>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>听《<a href="http://www.loveq.cn/" target="_blank" rel="external">一些事一些情
Swift学习笔记(三)
http://www.xayoung.cn/2016/05/02/Swift学习笔记(三)/
2016-05-02T04:13:25.000Z
2016-05-02T04:15:05.000Z
<h1 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h1><blockquote>
<p>一个类可以继承(inherit)另一个类的方法(methods),属性(properties)和其它特性。当一个类继承其它类时,继承类叫子类(subclass),被继承类叫超类(或父类,superclass)。在 Swift 中,继承是区分「类」与其它类型的一个基本特征。<br>在 Swift 中,类可以调用和访问超类的方法,属性和下标(subscripts),并且可以重写(override)这些方法,属性和下标来优化或修改它们的行为。Swift 会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为是正确的。</p>
</blockquote>
<hr>
<h2 id="父类"><a href="#父类" class="headerlink" title="父类"></a>父类</h2><blockquote>
<p>不继承于其它类的类,称之为基类(base class)。注意:Swift 中的类并不是从一个通用的基类继承而来。如果你不为你定义的类指定一个超类的话,这个类就自动成为基类。</p>
</blockquote>
<p>这里的控制器继承于UIViewController<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> UIKit</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HappinessViewController</span>: <span class="title">UIViewController</span>, <span class="title">FaceViewDataSource</span> </span>{</span><br><span class="line">......</span><br><span class="line"><span class="keyword">var</span> happiness: <span class="type">Int</span> = <span class="number">10</span> {</span><br><span class="line"><span class="keyword">didSet</span>{</span><br><span class="line">happiness = <span class="built_in">min</span>(<span class="built_in">max</span>(happiness, <span class="number">0</span>), <span class="number">100</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">"happiness = \(happiness)"</span>)</span><br><span class="line">updateUI()</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">func</span> <span class="title">updateUI</span><span class="params">()</span></span> {</span><br><span class="line">faceView?.setNeedsDisplay()</span><br><span class="line">title = <span class="string">"\(happiness)"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">smilinessForFaceView</span><span class="params">(sender: FaceView)</span></span> -> <span class="type">Double</span>? {</span><br><span class="line"><span class="keyword">return</span> <span class="type">Double</span>(happiness - <span class="number">50</span>)/<span class="number">50</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<hr>
<h2 id="子类"><a href="#子类" class="headerlink" title="子类"></a>子类</h2><blockquote>
<p>子类生成(Subclassing)指的是在一个已有类的基础上创建一个新的类。子类继承超类的特性,并且可以进一步完善。你还可以为子类添加新的特性。</p>
</blockquote>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> UIKit</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DianosedHappinessViewController</span>: <span class="title">HappinessViewController</span>, <span class="title">UIPopoverPresentationControllerDelegate</span></span>{</span><br><span class="line"><span class="keyword">override</span> <span class="keyword">var</span> happiness: <span class="type">Int</span>{</span><br><span class="line"><span class="comment">//先执行父类didSet,后执行子类的didSet。不会覆盖</span></span><br><span class="line"><span class="keyword">didSet</span>{</span><br><span class="line">dianosticHistory += [happiness]</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">····</span><br></pre></td></tr></table></figure>
<hr>
<h1 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h1><blockquote>
<p>方法是与某些特定类型相关联的函数。类、结构体、枚举都可以定义实例方法;实例方法为给定类型的实例封装了具体的任务与功能。类、结构体、枚举也可以定义类型方法;类型方法与类型本身相关联。类型方法与 Objective-C 中的类方法(class methods)相似。<br>结构体和枚举能够定义方法是 Swift 与 C/Objective-C 的主要区别之一。在 Objective-C 中,类是唯一能定义方法的类型。但在 Swift 中,你不仅能选择是否要定义一个类/结构体/枚举,还能灵活地在你创建的类型(类/结构体/枚举)上定义方法。</p>
</blockquote>
<p>定义运算方法<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//压入栈函数</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">pushOperand</span><span class="params">(operand: Double)</span></span> -> <span class="type">Double</span>?{</span><br><span class="line">opStack.append(<span class="type">Op</span>.<span class="type">Operand</span>(operand))</span><br><span class="line"><span class="keyword">return</span> evaluate()</span><br><span class="line">}</span><br><span class="line"><span class="comment">//传入运算符,执行运算</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">performOperation</span><span class="params">(symbol: String)</span></span> -> <span class="type">Double</span>?{</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">let</span> operation = knownOps[symbol]{</span><br><span class="line">opStack.append(operation)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> evaluate()</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>调用<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//运算</span></span><br><span class="line"><span class="meta">@IBAction</span> <span class="function"><span class="keyword">func</span> <span class="title">operate</span><span class="params">(sender: UIButton)</span></span> {</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> userIsInTheMiddleOfTypingANumber {</span><br><span class="line">enter()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">let</span> operation = sender.currentTitle {</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">let</span> result = brain.performOperation(operation){</span><br><span class="line">displayValue = result</span><br><span class="line">} <span class="keyword">else</span>{</span><br><span class="line">displayValue = <span class="number">0</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="meta">@IBAction</span> <span class="function"><span class="keyword">func</span> <span class="title">enter</span><span class="params">()</span></span> {</span><br><span class="line">userIsInTheMiddleOfTypingANumber = <span class="literal">false</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">let</span> result = brain.pushOperand(displayValue){</span><br><span class="line">displayValue = result</span><br><span class="line">} <span class="keyword">else</span>{</span><br><span class="line">displayValue = <span class="number">0</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<hr>
<h1 id="构造过程"><a href="#构造过程" class="headerlink" title="构造过程"></a>构造过程</h1><blockquote>
<p>构造过程是使用类、结构体或枚举类型的实例之前的准备过程。在新实例可用前必须执行这个过程,具体操作包括设置实例中每个存储型属性的初始值和执行其他必须的设置或初始化工作。<br>通过定义构造器(Initializers)来实现构造过程,这些构造器可以看做是用来创建特定类型新实例的特殊方法。与 Objective-C 中的构造器不同,Swift 的构造器无需返回值,它们的主要任务是保证新实例在第一次使用前完成正确的初始化。</p>
</blockquote>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//定义字典,key为运算符,value为Op,即运算方法</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">var</span> knownOps = <span class="type">Dictionary</span><<span class="type">String</span>, <span class="type">Op</span>>()</span><br><span class="line"><span class="keyword">init</span>() {</span><br><span class="line">knownOps[<span class="string">"×"</span>] = <span class="type">Op</span>.<span class="type">BinaryOperation</span>(<span class="string">"×"</span>, *)</span><br><span class="line">knownOps[<span class="string">"÷"</span>] = <span class="type">Op</span>.<span class="type">BinaryOperation</span>(<span class="string">"÷"</span>) {$<span class="number">1</span> / $<span class="number">0</span>}</span><br><span class="line">knownOps[<span class="string">"-"</span>] = <span class="type">Op</span>.<span class="type">BinaryOperation</span>(<span class="string">"-"</span>) {$<span class="number">1</span> - $<span class="number">0</span>}</span><br><span class="line">knownOps[<span class="string">"+"</span>] = <span class="type">Op</span>.<span class="type">BinaryOperation</span>(<span class="string">"+"</span>, +)</span><br><span class="line">knownOps[<span class="string">"√"</span>] = <span class="type">Op</span>.<span class="type">UnaryOperation</span>(<span class="string">"√"</span>, sqrt)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h1><p>最后展示截止到课时7,demo效果图。附上代码的github连接:<a href="https://github.com/xayoung/CS193P-DemoCode" target="_blank" rel="external">https://github.com/xayoung/CS193P-DemoCode</a><br><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f3gwzfornwg20l90fxjzb.gif" alt="此处输入图片的描述"></p>
<h1 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h1><blockquote>
<p>一个类可以继承(inherit)另一个类的方法(methods),属性(properties)和其它特性。当一个类
Swift学习笔记(二)
http://www.xayoung.cn/2016/04/10/Swift学习笔记(二)/
2016-04-10T06:51:35.000Z
2016-04-10T06:53:23.000Z
<h1 id="String"><a href="#String" class="headerlink" title="String"></a>String</h1><blockquote>
<p>Swift 的String和Character类型提供了一个快速的,兼容 Unicode 的方式来处理代码中的文本信息。 创建和操作字符串的语法与 C 语言中字符串操作相似,轻量并且易读。 字符串连接操作只需要简单地通过+号将两个字符串相连即可。 与 Swift 中其他值一样,能否更改字符串的值,取决于其被定义为常量还是变量。</p>
</blockquote>
<h2 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h2><p>定义一个变量,它的类型是String,值为“xayoung”<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br></pre></td></tr></table></figure></p>
<h2 id="字符串可变性-String-Mutability"><a href="#字符串可变性-String-Mutability" class="headerlink" title="字符串可变性 (String Mutability)"></a>字符串可变性 (String Mutability)</h2><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">CoderX</span> += <span class="string">"is a coder!"</span></span><br><span class="line"><span class="comment">//CoderX现在为"xayoung is a coder"</span></span><br></pre></td></tr></table></figure>
<p>可变性中与OC的不同点</p>
<blockquote>
<p>在 Objective-C 和 Cocoa 中,您通过选择两个不同的类(NSString和NSMutableString)来指定该字符串是否可以被修改,Swift 中的字符串是否可以修改仅通过定义的是变量还是常量来决定,实现了多种类型可变性操作的统一。</p>
</blockquote>
<h2 id="其他不同点"><a href="#其他不同点" class="headerlink" title="其他不同点"></a>其他不同点</h2><blockquote>
<p>String 和 NSString 有着良好的互相转换的特性,但是现在 Cocoa 所有的 API 都接受和返回 String 类型。但Swift 中 String 是 struct,相比起 NSObject 的 NSString 类来说,更切合字符串的 “不变” 这一特性。通过配合常量赋值 (let) ,这种不变性在多线程编程时就非常重要了,它从原理上将程序员从内存访问和操作顺序的担忧中解放出来。另外,在不触及 NSString 特有操作和动态特性的时候,使用 String 的方法,在性能上也会有所提升。</p>
</blockquote>
<p>String特有的一些特性<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="type">Coder</span> = <span class="string">"xayoung"</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="type">Coder</span>.characters {</span><br><span class="line"><span class="built_in">print</span>(i)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<hr>
<h1 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h1><blockquote>
<p>在 Swift 中,枚举类型是一等(first-class)类型。它们采用了很多传统上只被类(class)所支持的特征,例如计算型属性(computed properties),用于提供关于枚举当前值的附加信息, 实例方法(instance methods),用于提供和枚举所代表的值相关联的功能。枚举也可以定义构造函数(initializers)来提供一个初始成员值;可以在原始的实现基础上扩展它们的功能;可以遵守协议(protocols)来提供标准的功能。</p>
</blockquote>
<h2 id="定义-1"><a href="#定义-1" class="headerlink" title="定义"></a>定义</h2><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">enum</span> <span class="title">Eye</span> </span>{ </span><br><span class="line"><span class="keyword">case</span> <span class="type">Left</span>, <span class="type">Right</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>不像 C 和 Objective-C 一样,Swift 的枚举成员在被创建时不会被赋予一个默认的整数值。在上面的CompassPoints例子中,North,South,East和West不是隐式的等于0,1,2和3。相反的,这些不同的枚举成员在CompassPoint的一种显示定义中拥有各自不同的值。</p>
</blockquote>
<h2 id="匹配枚举值和Switch语句"><a href="#匹配枚举值和Switch语句" class="headerlink" title="匹配枚举值和Switch语句"></a>匹配枚举值和Switch语句</h2><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> whichEye = <span class="type">Eye</span>.<span class="type">Left</span></span><br><span class="line"><span class="keyword">switch</span> whichEye {</span><br><span class="line"><span class="keyword">case</span> .<span class="type">Left</span>: eyeCenter.x -= eyeHorizontalSeparation / <span class="number">2</span></span><br><span class="line"><span class="keyword">case</span> .<span class="type">Right</span>: eyeCenter.x += eyeHorizontalSeparation / <span class="number">2</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>如在控制流(Control Flow)中介绍,当考虑一个枚举的成员们时,一个switch语句必须全面。如果忽略了.West这种情况,上面那段代码将无法通过编译,因为它没有考虑到CompassPoint的全部成员。全面性的要求确保了枚举成员不会被意外遗漏。<br>当不需要匹配每个枚举成员的时候,你可以提供一个默认default分支来涵盖所有未明确被提出的任何成员</p>
</blockquote>
<hr>
<h1 id="类和结构体"><a href="#类和结构体" class="headerlink" title="类和结构体"></a>类和结构体</h1><h2 id="类和结构体对比"><a href="#类和结构体对比" class="headerlink" title="类和结构体对比"></a>类和结构体对比</h2><p>Swift 中类和结构体有很多共同点。共同处在于:</p>
<ul>
<li>定义属性用于存储值</li>
<li>定义方法用于提供功能</li>
<li>定义附属脚本用于访问值</li>
<li>定义构造器用于生成初始化值</li>
<li>通过扩展以增加默认实现的功能</li>
<li>符合协议以对某类提供标准功能</li>
</ul>
<p>与结构体相比,类还有如下的附加功能:</p>
<ul>
<li>继承允许一个类继承另一个类的特征</li>
<li>类型转换允许在运行时检查和解释一个类实例的类型</li>
<li>解构器允许一个类实例释放任何其所被分配的资源</li>
<li>引用计数允许对一个类的多次引用</li>
</ul>
<h2 id="定义-2"><a href="#定义-2" class="headerlink" title="定义"></a>定义</h2><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VideoMode</span> </span>{</span><br><span class="line"><span class="keyword">var</span> resolution = <span class="type">Resolution</span>()</span><br><span class="line"><span class="keyword">var</span> interlaced = <span class="literal">false</span></span><br><span class="line"><span class="keyword">var</span> frameRate = <span class="number">0.0</span></span><br><span class="line"><span class="keyword">var</span> name: <span class="type">String</span>?</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>上边定义了一个名为VideoMode的类,用来描述一个视频显示器的特定模式。这个类包含了四个储存属性变量。第一个是分辨率,它被初始化为一个新的Resolution结构体的实例,具有Resolution的属性类型。新VideoMode实例同时还会初始化其它三个属性,它们分别是,初始值为false(意为“non-interlaced video”)的interlaced,回放帧率初始值为0.0的frameRate和值为可选String的name。name属性会被自动赋予一个默认值nil,意为“没有name值”,因为它是一个可选类型。</p>
</blockquote>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Scaling</span> </span>{</span><br><span class="line"><span class="keyword">let</span> <span class="type">FaceRadiusToEyeRadiusRatio</span>: <span class="type">CGFloat</span> = <span class="number">10</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">FaceRadiusToEyeOffsetRatio</span>: <span class="type">CGFloat</span> = <span class="number">3</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">FaceRadiusToEyeSeparationRatio</span>: <span class="type">CGFloat</span> = <span class="number">1.5</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">FaceRadiusToMouthWidthRatio</span>: <span class="type">CGFloat</span> = <span class="number">1</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">FaceRadiusToMouthHeightRatio</span>: <span class="type">CGFloat</span> = <span class="number">3</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">FaceRadiusToMouthOffsetRatio</span>: <span class="type">CGFloat</span> = <span class="number">3</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="属性访问"><a href="#属性访问" class="headerlink" title="属性访问"></a>属性访问</h2><p>通过使用点语法(dot syntax),你可以访问实例中所含有的属性。其语法规则是,实例名后面紧跟属性名,两者通过点号(.)连接<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> mouthWidth = faceRadius / <span class="type">Scaling</span>.<span class="type">FaceRadiusToMouthWidthRatio</span></span><br></pre></td></tr></table></figure></p>
<p>也可以使用点语法为属性变量赋值:<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Scaling</span>.<span class="type">FaceRadiusToMouthWidthRatio</span> = <span class="number">50.0</span></span><br></pre></td></tr></table></figure></p>
<blockquote>
<p> 与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的最后一个例子,就是直接设置了someVideoMode中resolution属性的width这个子属性,以上操作并不需要重新设置resolution属性。</p>
</blockquote>
<h2 id="注意点"><a href="#注意点" class="headerlink" title="注意点"></a>注意点</h2><blockquote>
<p>在 Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Booleans)、字符串(string)、数组(array)和字典(dictionaries),都是值类型,并且都是以结构体的形式在后台所实现。<br>在 Swift 中,所有的结构体和枚举都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。<br>而类是引用类型,与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,操作的是引用,其并不是拷贝。因此,引用的是已存在的实例本身而不是其拷贝。</p>
</blockquote>
<hr>
<h1 id="协议"><a href="#协议" class="headerlink" title="协议"></a>协议</h1><blockquote>
<p>协议(Protocol)用于定义完成某项任务或功能所必须的方法和属性,协议实际上并不提供这些功能或任务的具体实现(Implementation)–而只用来描述这些实现应该是什么样的。类,结构体,枚举通过提供协议所要求的方法,属性的具体实现来采用(adopt)协议。任意能够满足协议要求的类型被称为协议的遵循者。</p>
</blockquote>
<p>代理模式<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//声明datasource协议,这里需要把FaceVireDataSource变成一个类才能实现的协议,</span></span><br><span class="line"><span class="class"><span class="keyword">protocol</span> <span class="title">FaceViewDataSource</span>: <span class="title">class</span> </span>{</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">smilinessForFaceView</span><span class="params">(sender: FaceView)</span></span> -> <span class="type">Double</span>?</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>实现代理方法<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用操作符??,左侧有值使用它的值,左侧为nil时则使用右侧</span></span><br><span class="line"><span class="keyword">let</span> smiliness = dataSource?.smilinessForFaceView(<span class="keyword">self</span>) ?? <span class="number">0.0</span></span><br></pre></td></tr></table></figure></p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HappinessViewController</span>: <span class="title">UIViewController</span>, <span class="title">FaceViewDataSource</span> </span>{</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置datasource代理</span></span><br><span class="line"><span class="meta">@IBOutlet</span> <span class="keyword">weak</span> <span class="keyword">var</span> faceView: <span class="type">FaceView</span>! {</span><br><span class="line"><span class="keyword">didSet</span> {</span><br><span class="line">faceView.dataSource = <span class="keyword">self</span></span><br><span class="line">faceView.addGestureRecognizer(<span class="type">UIPinchGestureRecognizer</span>(target: faceView, action: <span class="string">"scale:"</span>))</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<hr>
<h1 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h1><p>最后展示截止到课时6,最新的demo效果图。附上代码的github连接:<a href="https://github.com/xayoung/CS193P-DemoCode" target="_blank" rel="external">https://github.com/xayoung/CS193P-DemoCode</a><br><img src="http://7xqnsr.com1.z0.glb.clouddn.com/44.gif" alt="此处输入图片的描述"></p>
<h1 id="String"><a href="#String" class="headerlink" title="String"></a>String</h1><blockquote>
<p>Swift 的String和Character类型提供了一个快速的,兼容 Unic
Swift学习笔记(一)
http://www.xayoung.cn/2016/04/03/Swift学习笔记(一)/
2016-04-03T06:49:44.000Z
2016-04-03T06:53:36.000Z
<p>学习Swift的方向:通过斯坦福大学公开课-<a href="http://open.163.com/special/opencourse/ios8.html" target="_blank" rel="external">CS193P iPhone Application Development</a>的课程,结合苹果官方教程-<a href="https://numbbbbb.gitbooks.io/-the-swift-programming-language-/content/chapter1/01_swift.html" target="_blank" rel="external">《The Swift Programming Language》</a>中文版,逐步了解Swift语法,与Obective-C全面对比,掌握Swift各种特性跟上苹果的节奏。</p>
<h2 id="常量与变量"><a href="#常量与变量" class="headerlink" title="常量与变量"></a>常量与变量</h2><p>OC中,我们一般这样声明宏、常量和变量<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//宏</span></span><br><span class="line"><span class="meta">#define CoderX @<span class="meta-string">"xayoung"</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//变量</span></span><br><span class="line"><span class="built_in">NSString</span> *CoderX;</span><br><span class="line"></span><br><span class="line"><span class="comment">//常量</span></span><br><span class="line"><span class="built_in">NSString</span> * <span class="keyword">const</span> CoderX = <span class="string">@"xayoung"</span>;</span><br></pre></td></tr></table></figure></p>
<p>在Swift中,使用<code>let</code>、<code>var</code>分别定义常量和变量</p>
<blockquote>
<p>声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。<br>注意点:一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。</p>
</blockquote>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//常量</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">CoderX</span></span><br><span class="line"><span class="comment">//or</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br></pre></td></tr></table></figure>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//变量</span></span><br><span class="line"><span class="keyword">var</span> <span class="type">CoderX</span></span><br><span class="line"><span class="comment">//or</span></span><br><span class="line"><span class="keyword">var</span> <span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br><span class="line"><span class="comment">//or</span></span><br><span class="line"><span class="keyword">var</span> <span class="type">CoderX</span>: <span class="type">String</span></span><br><span class="line"><span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br></pre></td></tr></table></figure>
<h2 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h2><p>在OC中我们一般使用<code>NSLog</code>进行输出<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"xayoung is a coder!"</span>);</span><br><span class="line"><span class="comment">//or</span></span><br><span class="line"><span class="built_in">NSString</span> *CoderX = <span class="string">@"xayoung is a coder!"</span></span><br><span class="line"><span class="built_in">NSLog</span>(<span class="string">@"%@"</span>,CoderX);</span><br></pre></td></tr></table></figure></p>
<p>Swift则通过<code>print</code>进行输出<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="string">"xayoung is a coder!"</span>)</span><br><span class="line"><span class="keyword">var</span> <span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">"\(CoderX) is a coder!"</span>)</span><br></pre></td></tr></table></figure></p>
<h2 id="类型安全和类型推断"><a href="#类型安全和类型推断" class="headerlink" title="类型安全和类型推断"></a>类型安全和类型推断</h2><blockquote>
<p> Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。<br>当你要处理不同类型的值时,类型检查可以帮你避免错误。然而,这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型,Swift 会使用类型推断(type inference)来选择合适的类型。有了类型推断,编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单,只要检查你赋的值即可。因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。<br>常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。</p>
</blockquote>
<p>在定义常量的时候,下方的常量<code>CoderX</code>会被推断为<code>String</code>类型<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//常量</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">CoderX</span></span><br><span class="line"><span class="comment">//or</span></span><br><span class="line"><span class="keyword">let</span> <span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br></pre></td></tr></table></figure></p>
<p>如果定义的时候声明类型,就只能传入该类型的值<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="type">CoderX</span>: <span class="type">String</span></span><br><span class="line"><span class="type">CoderX</span> = <span class="string">"xayoung"</span></span><br></pre></td></tr></table></figure></p>
<h2 id="可选类型"><a href="#可选类型" class="headerlink" title="可选类型"></a>可选类型</h2><blockquote>
<p>C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回nil,nil表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如NSNotFound)来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而,Swift 的可选类型可以让你暗示任意类型的值缺失,并不需要一个特殊值。</p>
</blockquote>
<p>如CS193P公开课代码实例中就展示了这个概念<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@IBOutlet</span> <span class="keyword">weak</span> <span class="keyword">var</span> display: <span class="type">UILabel</span>!</span><br><span class="line"></span><br><span class="line"><span class="comment">//点击button方法</span></span><br><span class="line"><span class="meta">@IBAction</span> <span class="function"><span class="keyword">func</span> <span class="title">appendDigit</span><span class="params">(sender: UIButton)</span></span> {</span><br><span class="line"><span class="comment">//默认是Optional类型,通过!将button的值解包</span></span><br><span class="line"><span class="keyword">let</span> digit = sender.currentTitle!</span><br><span class="line"><span class="keyword">if</span> userIsInTheMiddleOfTypingANumber{</span><br><span class="line">display.text = display.text! + digit</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line">display.text = digit</span><br><span class="line">userIsInTheMiddleOfTypingANumber = <span class="literal">true</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><blockquote>
<p>Swift 统一的函数语法足够灵活,可以用来表示任何函数,包括从最简单的没有参数名字的 C 风格函数,到复杂的带局部和外部参数名的 Objective-C 风格函数。参数可以提供默认值,以简化函数调用。参数也可以既当做传入参数,也当做传出参数,也就是说,一旦函数执行结束,传入的参数值可以被修改。<br>在 Swift 中,每个函数都有一种类型,包括函数的参数值类型和返回值类型。你可以把函数类型当做任何其他普通变量类型一样处理,这样就可以更简单地把函数当做别的函数的参数,也可以从其他函数中返回函数。函数的定义可以写在在其他函数定义中,这样可以在嵌套函数范围内实现功能封装。</p>
</blockquote>
<p>在OC中,我们一般这么定义函数<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">-(<span class="keyword">double</span>)preformOperationxWithDouble1:(<span class="keyword">double</span> )d1 Double2:(<span class="keyword">double</span> )d2;</span><br></pre></td></tr></table></figure></p>
<p>Swift更简洁<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">preformOperationx</span><span class="params">(operation:<span class="params">(Double, Double)</span></span></span>-> <span class="type">Double</span>)</span><br></pre></td></tr></table></figure></p>
<p>CS193P公开课中计算器的实现方法<br><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//运算</span></span><br><span class="line"><span class="meta">@IBAction</span> <span class="function"><span class="keyword">func</span> <span class="title">operate</span><span class="params">(sender: UIButton)</span></span> {</span><br><span class="line"><span class="keyword">let</span> operation = sender.currentTitle!</span><br><span class="line"><span class="keyword">if</span> userIsInTheMiddleOfTypingANumber {</span><br><span class="line">enter()</span><br><span class="line">}</span><br><span class="line"><span class="keyword">switch</span> operation {</span><br><span class="line"><span class="comment">//给preformOperationx传入函数{ $0 * $1 },返回一个double</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">"×"</span>: preformOperationx(){ $<span class="number">0</span> * $<span class="number">1</span> }</span><br><span class="line"><span class="keyword">case</span> <span class="string">"÷"</span>: preformOperationx(){ $<span class="number">1</span> / $<span class="number">0</span> }</span><br><span class="line"><span class="keyword">case</span> <span class="string">"+"</span>: preformOperationx(){ $<span class="number">0</span> + $<span class="number">1</span> }</span><br><span class="line"><span class="keyword">case</span> <span class="string">"-"</span>: preformOperationx(){ $<span class="number">1</span> - $<span class="number">0</span> }</span><br><span class="line"><span class="comment">//函数虽然同名,但是swift会推断传入的参数调用哪个方法</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">"√"</span>: preformOperationx(){ sqrt($<span class="number">0</span>)}</span><br><span class="line"><span class="keyword">default</span>:<span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="comment">//自定义函数,复用运算的代码</span></span><br><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">func</span> <span class="title">preformOperationx</span><span class="params">(operation:<span class="params">(Double, Double)</span></span></span>-> <span class="type">Double</span>) {</span><br><span class="line"><span class="keyword">if</span> operandStark.<span class="built_in">count</span> >= <span class="number">2</span> {</span><br><span class="line">displayValue = operation(operandStark.removeLast() , operandStark.removeLast())</span><br><span class="line">enter()</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">func</span> <span class="title">preformOperationx</span><span class="params">(operation:<span class="params">(Double)</span></span></span>-> <span class="type">Double</span>) {</span><br><span class="line"><span class="keyword">if</span> operandStark.<span class="built_in">count</span> >= <span class="number">1</span> {</span><br><span class="line">displayValue = operation(operandStark.removeLast())</span><br><span class="line">enter()</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>课程示例程序截图</p>
<p><img src="http://ww4.sinaimg.cn/large/5e999b55gw1f2jifbfyhtj20af0ij0su.jpg" alt="此处输入图片的描述"></p>
<p>附上代码的github连接:<a href="https://github.com/xayoung/CS193P-DemoCode" target="_blank" rel="external">https://github.com/xayoung/CS193P-DemoCode</a></p>
<p>课程视频截图</p>
<p><img src="http://ww1.sinaimg.cn/large/5e999b55gw1f2jifugap7j20nv0dhdin.jpg" alt="此处输入图片的描述"></p>
<h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>通过两个课时的讲解,并结合苹果官方的《The Swift Programming Language》,对Swift有了基本的认识,老头子讲得很仔细很透彻,一个不错的开始😊</p>
<p>学习Swift的方向:通过斯坦福大学公开课-<a href="http://open.163.com/special/opencourse/ios8.html" target="_blank" rel="external">CS193P iPhone Application
UITableViewCell实现多选(自定义排序)
http://www.xayoung.cn/2016/03/31/UITableViewCell实现多选(自定义排序)/
2016-03-31T12:42:39.000Z
2016-03-31T13:03:31.000Z
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>工作项目中有这样一个需求:目标控制器使用TableView展示一组网络请求返回的数组,由上一个控制器push过来时传入一个或多个该数组的元素,需要在展示时优先展示并默认选中传进来的数据。</p>
<hr>
<h2 id="需求分析"><a href="#需求分析" class="headerlink" title="需求分析"></a>需求分析</h2><h2 id=""><a href="#" class="headerlink" title=""></a><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f2g6vmfwufj20h60ahq3c.jpg" alt="此处输入图片的描述"></h2><hr>
<h2 id="功能实现"><a href="#功能实现" class="headerlink" title="功能实现"></a>功能实现</h2><p>首先将接收到的元素截取并存入数组,并打开TableView编辑模式<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//进入编辑模式</span></span><br><span class="line">[<span class="keyword">self</span>.tableView setEditing:<span class="literal">YES</span> animated:<span class="literal">YES</span>];</span><br><span class="line"><span class="comment">//接收ID,截取为数组</span></span><br><span class="line">draftSendID = [<span class="built_in">NSMutableArray</span> arrayWithArray:[<span class="keyword">self</span>.receiverIds componentsSeparatedByString:<span class="string">@","</span>]];<span class="comment">//数组</span></span><br></pre></td></tr></table></figure></p>
<p>发送网络请求,将返回的JSON模型化并存入数组,根据上一个上一个控制器传入的ID进行比对排序。<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">[infoarray addObject:[ReceiversModel instanceWithDict:item]];</span><br><span class="line"><span class="comment">//排序</span></span><br><span class="line"><span class="built_in">NSArray</span> *array1 = [infoarray sortedArrayUsingComparator:^<span class="built_in">NSComparisonResult</span>(<span class="keyword">id</span> obj1, <span class="keyword">id</span> obj2) {</span><br><span class="line"></span><br><span class="line">ReceiversModel *model1 = [[ReceiversModel alloc]init];</span><br><span class="line">model1 = obj1;</span><br><span class="line">ReceiversModel *model2 = [[ReceiversModel alloc]init];</span><br><span class="line">model2 = obj2;</span><br><span class="line"><span class="keyword">if</span> (![draftSendID containsObject:model1.receiverId] ){</span><br><span class="line"><span class="keyword">return</span> <span class="built_in">NSOrderedDescending</span>;</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>([draftSendID containsObject:model1.receiverId]){</span><br><span class="line"><span class="keyword">return</span> <span class="built_in">NSOrderedAscending</span>;</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">return</span> <span class="built_in">NSOrderedSame</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}];</span><br></pre></td></tr></table></figure></p>
<p>数据源中实现选中<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">- (<span class="built_in">UITableViewCell</span> *)tableView:(<span class="built_in">UITableView</span> *)tableView cellForRowAtIndexPath:(<span class="built_in">NSIndexPath</span> *)indexPath {</span><br><span class="line">...</span><br><span class="line">...</span><br><span class="line">...</span><br><span class="line">ReceiversModel *model = infoarray[indexPath.row];</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ([draftSendID containsObject:model.receiverId] ) {</span><br><span class="line">[receiverIdsArray addObject:model];</span><br><span class="line">[<span class="keyword">self</span>.tableView selectRowAtIndexPath:indexPath animated:<span class="literal">YES</span> scrollPosition:<span class="built_in">UITableViewScrollPositionNone</span>];</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">[cell setCellWithModel:model];</span><br><span class="line"><span class="keyword">return</span> cell;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>以下三个TableView代理方法必须要实现<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">- (<span class="built_in">BOOL</span>)tableView:(<span class="built_in">UITableView</span> *)tableView canEditRowAtIndexPath:(<span class="built_in">NSIndexPath</span> *)indexPath{</span><br><span class="line"><span class="keyword">return</span> <span class="literal">YES</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">-(<span class="built_in">UITableViewCellEditingStyle</span>)tableView:(<span class="built_in">UITableView</span> *)tableView editingStyleForRowAtIndexPath:(<span class="built_in">NSIndexPath</span> *)indexPath{</span><br><span class="line"><span class="comment">//选中编辑模式</span></span><br><span class="line"><span class="keyword">return</span> <span class="built_in">UITableViewCellEditingStyleDelete</span> | <span class="built_in">UITableViewCellEditingStyleInsert</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (<span class="keyword">void</span>)tableView:(<span class="built_in">UITableView</span> *)tableView commitEditingStyle:(<span class="built_in">UITableViewCellEditingStyle</span>)editingStyle forRowAtIndexPath:(<span class="built_in">NSIndexPath</span> *)indexPath{</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>选中实现方法<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">- (<span class="keyword">void</span>)tableView:(<span class="built_in">UITableView</span> *)tableView didSelectRowAtIndexPath:(<span class="built_in">NSIndexPath</span> *)indexPath {</span><br><span class="line"></span><br><span class="line">ReceiversModel *model = infoarray[indexPath.row];</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (![receiverIdsArray containsObject:model] ) {</span><br><span class="line">[receiverIdsArray addObject:model];</span><br><span class="line">}</span><br><span class="line">[<span class="keyword">self</span>.tableView selectRowAtIndexPath:indexPath animated:<span class="literal">YES</span> scrollPosition:<span class="built_in">UITableViewScrollPositionNone</span>];</span><br><span class="line"><span class="comment">//可通过下方方法实现单选,此处不适用</span></span><br><span class="line"><span class="comment">// NSInteger newRow = [indexPath row];</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// NSInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;</span></span><br><span class="line"><span class="comment">// if (newRow != oldRow)</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// {</span></span><br><span class="line"><span class="comment">// [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];</span></span><br><span class="line"><span class="comment">// UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// oldCell.accessoryType = UITableViewCellAccessoryNone;</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// [tableView deselectRowAtIndexPath:lastIndexPath animated:YES];</span></span><br><span class="line"><span class="comment">// lastIndexPath = [indexPath copy];</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// }else{</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// }</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>取消选中方法,进行判断<br><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">- (<span class="keyword">void</span>)tableView:(<span class="built_in">UITableView</span> *)tableView didDeselectRowAtIndexPath:(<span class="built_in">NSIndexPath</span> *)indexPath{</span><br><span class="line">ReceiversModel *model = infoarray[indexPath.row];</span><br><span class="line"><span class="keyword">if</span> ([receiverIdsArray containsObject:model] ) {</span><br><span class="line">[receiverIdsArray removeObject:model];</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>最后再拼接字符串通过代理回传到上一个控制器就o了</p>
<hr>
<h2 id="大功告成"><a href="#大功告成" class="headerlink" title="大功告成"></a>大功告成</h2><h2 id="-1"><a href="#-1" class="headerlink" title=""></a><img src="http://ww1.sinaimg.cn/large/5e999b55gw1f2g7qtgsl0j20af0ijaas.jpg" alt="此处输入图片的描述"></h2>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>工作项目中有这样一个需求:目标控制器使用TableView展示一组网络请求返回的数组,由上一个控制器push过来时传入一个或多个该数组的元素
Swift语言指南
http://www.xayoung.cn/2016/03/24/Swift语言指南/
2016-03-24T12:57:37.000Z
2016-04-03T03:31:38.000Z
<hr>
<p>本文转载自:<a href="https://github.com/ipader/SwiftGuide" target="_blank" rel="external">https://github.com/ipader/SwiftGuide</a></p>
<blockquote>
<p>2016.3.21苹果发布会更新了Swift2.2版本,感觉差不多可以开始接触,准备上手学习,转载份指南作为参考。</p>
</blockquote>
<p> <a href="https://github.com/ipader/SwiftGuide/blob/master/2014%20letter.md" target="_blank" rel="external">这份指南</a>汇集了 Swift 语言主流学习资源,并以开发者的视角整理编排。对于精选项目及文章,可直接访问《<a href="https://github.com/ipader/SwiftGuide/blob/master/Featured.md" target="_blank" rel="external">Swift 项目精选</a>》和《<a href="https://github.com/ipader/SwiftGuide/blob/master/Featured-Articles.md" target="_blank" rel="external">Swift 文章精选</a>》。</p>
<h2 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h2><ul>
<li><a href="#welcome">入门指引</a></li>
<li><a href="#swift_courses">教程文章</a></li>
<li><a href="#swift_projects">开源项目</a></li>
<li><a href="#recomm_sites">推荐网站</a></li>
<li><a href="#tools">开发工具</a></li>
<li><a href="https://github.com/ipader/SwiftGuide/tree/master/archive/news.md" target="_blank" rel="external">媒体报道</a></li>
<li><a href="https://github.com/ipader/SwiftGuide/tree/master/archive/platforms.md" target="_blank" rel="external">开放平台</a></li>
<li><a href="https://github.com/ipader/SwiftGuide/blob/master/Apple%20Watch/README.md" target="_blank" rel="external">Apple Watch 指南</a></li>
</ul>
<hr>
<h2 id="入门指引"><a href="#入门指引" class="headerlink" title="入门指引"></a><a id="welcome"></a>入门指引</h2><p>苹果为为 <a href="http://www.apple.com/swift/" target="_blank" rel="external">Swift</a>(<a href="http://www.apple.com/cn/swift/" target="_blank" rel="external">中文介绍</a>)开发者提供的<a href="https://developer.apple.com/swift/" target="_blank" rel="external">官方文档入口</a>,包括 <a href="https://developer.apple.com/swift/" target="_blank" rel="external">概述</a>,<a href="https://developer.apple.com/swift/blog/" target="_blank" rel="external">博客</a>(<a href="https://github.com/ipader/SwiftGuide/tree/master/mirror/Swift%20Blog%20-%20Apple%20Developer" target="_blank" rel="external">中文镜像</a>)及 <a href="https://developer.apple.com/swift/resources/" target="_blank" rel="external">开发资源</a>。其中以下几份文档(Swift 2.1)为入门级必备(<a href="https://itunes.apple.com/us/book-series/swift-programming-series/id888896989?mt=11" target="_blank" rel="external">iBooks 版</a>):</p>
<ul>
<li><p><a href="https://developer.apple.com/swift/" target="_blank" rel="external">Swift Programming Language</a>(<a href="http://gg.swiftguide.cn" target="_blank" rel="external">中文版</a>|<a href="http://wiki.jikexueyuan.com/download/swift/pdf/" target="_blank" rel="external">PDF 版</a> By <a href="http://weibo.com/swiftguide" target="_blank" rel="external">SwiftGG翻译组</a>)</p>
</li>
<li><p><a href="https://developer.apple.com/swift/resources/" target="_blank" rel="external">Start Developing iOS Apps</a> </p>
</li>
<li><a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html" target="_blank" rel="external">Using Swift with Cocoa and Objective-C</a>(<a href="https://github.com/CocoaChina-editors/Welcome-to-Swift/blob/master/UsingSwiftwithCocoaandObjective-C%E4%B8%AD%E6%96%87%E6%89%8B%E5%86%8C.md" target="_blank" rel="external">中文版</a> By <a href="http://weibo.com/cocoachina" target="_blank" rel="external">@CocoaChina</a>)</li>
</ul>
<p><em>苹果同时也维护着相应 Beta 版(Swift 2.2)文档:<a href="https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html" target="_blank" rel="external">Swift Programming Language</a>,<a href="https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/index.html" target="_blank" rel="external">Start Developing iOS Apps</a>,<a href="https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html" target="_blank" rel="external">Using Swift with Cocoa and Objective-C</a>。</em></p>
<p>学习实践的角度,标准库示例代码 <a href="https://developer.apple.com/sample-code/swift/downloads/Standard-Library.zip" target="_blank" rel="external">Swift Standard Library.playground</a> 是很棒的学习伴侣。</p>
<p>教程方面,苹果力荐了斯坦福课程 <a href="https://itunes.com/StanfordSwift" target="_blank" rel="external">Stanford University: Developing iOS 8 Apps with Swift</a>(<a href="http://open.163.com/special/opencourse/ios8.html" target="_blank" rel="external">中文字幕版</a> By <a href="http://weibo.com/163open" target="_blank" rel="external">@网易公开课</a>)</p>
<p>除以上所涉及入门级文档,<a href="https://developer.apple.com/library/ios/navigation/" target="_blank" rel="external">iOS Developer Library</a> 还为开发者提供了更庞大、系统化的开发文档支持。</p>
<p>以下列举了几份已有第三方中文翻译文档:</p>
<ul>
<li><a href="https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/index.html" target="_blank" rel="external">App Extension Programming Guide</a>(<a href="https://github.com/ipader/SwiftGuide/tree/master/mirror/App%20Extension%20Programming%20Guide" target="_blank" rel="external">中译镜像</a>)</li>
<li><a href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/index.html" target="_blank" rel="external">iOS Human Interface Guidelines</a>(<a href="https://isux.tencent.com/?s=iOS+9+%E4%BA%BA%E6%9C%BA%E7%95%8C%E9%9D%A2%E6%8C%87%E5%8D%97" target="_blank" rel="external">中文版</a>|<a href="http://ixdc.org/2016/files/ISUX[%E8%AF%91]iOS9%20human%20Interface%20Guideline.pdf" target="_blank" rel="external">PDF 版</a> By <a href="http://weibo.com/txisux" target="_blank" rel="external">@腾讯ISUX</a>)</li>
<li><a href="https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/Introduction/Introduction.html" target="_blank" rel="external">HomeKit Developer Guide</a>(<a href="http://www.cocoachina.com/ios/20150324/11411.html" target="_blank" rel="external">中文版</a> By <a href="http://weibo.com/cocoachina" target="_blank" rel="external">@CocoaChina</a>)</li>
</ul>
<p>值得称道的还有:苹果为 <a href="https://developer.apple.com/videos/" target="_blank" rel="external">Apple TV Tech Talks</a> 和 <a href="https://developer.apple.com/videos/wwdc2015/" target="_blank" rel="external">WWDC 2015</a> 的视频添加简体中文字幕,从而方便中国开发者观看来自官方的权威技术分享。</p>
<p>有关于 Swift 开源及跨平台开发,可以关注 <a href="https://swift.org/" target="_blank" rel="external">swift.org</a></p>
<h2 id="教程文章"><a href="#教程文章" class="headerlink" title="教程文章"></a><a id="swift_courses"></a><a href="https://github.com/ipader/SwiftGuide/blob/master/Featured-Articles.md" target="_blank" rel="external">教程文章</a></h2><h2 id="开源项目"><a href="#开源项目" class="headerlink" title="开源项目"></a><a id="swift_projects"></a><a href="https://github.com/ipader/SwiftGuide/blob/master/Featured.md" target="_blank" rel="external">开源项目</a></h2><h2 id="推荐网站"><a href="#推荐网站" class="headerlink" title="推荐网站"></a><a id="recomm_sites"></a>推荐网站</h2><ul>
<li><strong>苹果官方</strong></li>
<li><a href="https://developer.apple.com/swift/" target="_blank" rel="external">Swift</a>:Swift 概述、博客以及开发资源。</li>
<li><a href="https://swift.org/" target="_blank" rel="external">swift.org</a>:开源后独立出来的 Swift 开源社区。</li>
<li><a href="https://github.com/apple" target="_blank" rel="external">GitHub:apple</a>:苹果在 GitHub 上的开源项目。</li>
<li><a href="https://github.com/apple/swift" target="_blank" rel="external">GitHub:apple/swift</a>:swift 语言在 GitHub 上的开源项目。</li>
<li><a href="https://github.com/ksm/SwiftInFlux" target="_blank" rel="external">ksm/SwiftInFlux</a>:作者(Karol Mazur)将 Apple Developer Forums 上有关 Swift 特性、缺陷及变更讨论分类汇总并更新到 GitHub,具有很好的可读性。从中可以一窥 Swift 缺陷及未来潜在地变化。最关键地是有 Chris Lattner 及核心团队答疑解惑。</li>
<li><a href="http://www.raywenderlich.com/" target="_blank" rel="external">raywenderlich.com</a>(<a href="http://www.raywenderlich.com/zh-hans/" target="_blank" rel="external">中文版</a>):由Ray Wenderlich创建,专注于开发高质量编程指南(近期优质Swift文章及视频教程不断),著名的iOS/OS X博客及开发教程网站,非常适合新手学习。近期第一时间出了<a href="http://www.raywenderlich.com/74832/three-new-swift-books" target="_blank" rel="external">三本 Swift 新书</a>。</li>
<li><a href="http://natashatherobot.com/" target="_blank" rel="external">Natasha The Robot</a>: 时髦码农不容错过的 Swift 开发实战教程类网站。为了简化学习复杂性,每一篇文章涵盖技术点单一又独立,配以开发步骤、运行结果以及代码等标准方式教授。难能可贵的是,它往往出品“追剧式”(最新开发特性或API跟进式)教程,实在是开发者必藏精品网站。</li>
<li><a href="http://nshipster.com/" target="_blank" rel="external">NShipster</a> (<a href="http://nshipster.cn/" target="_blank" rel="external">中译版</a>:<a href="http://weibo.com/croath" target="_blank" rel="external">@刘镇夫</a>,<a href="http://nshipster.cn/translators/april-peng/" target="_blank" rel="external">April Peng</a>,<a href="http://weibo.com/leelejia" target="_blank" rel="external">@李乐佳</a>,<a href="http://weibo.com/fallhunter" target="_blank" rel="external">@程序员付恒</a> 等翻译):著名开源作者 <a href="https://github.com/mattt" target="_blank" rel="external">Matt Thompson</a> 创建的开发技术博客网站,他开发了 <a href="https://github.com/afnetworking/afnetworking" target="_blank" rel="external">AFNetworking</a> 网络库,也是非常多产的开源作者。更多了解参考:<a href="http://www.fallhunter.com/p/10709" target="_blank" rel="external">《COCOA 潮人 MATTT THOMPSON》</a> By <a href="http://weibo.com/fallhunter" target="_blank" rel="external">@程序员付恒</a></li>
<li><a href="http://jamesonquave.com/blog/" target="_blank" rel="external">jamesonquave.com</a>:移动开发者,优秀个人博客(近期文章同样关注于Swift 语言,写得很优质)。同时他将于8/30发布一本新书<a href="http://jamesonquave.com/swiftebook/" target="_blank" rel="external">《Developing iOS 8 Apps in Swift》</a> (Learn To Make Real World iOS 8 Apps)及视频教程。</li>
<li><a href="https://www.objc.io/" target="_blank" rel="external">objc.io</a>(<a href="http://objccn.io" target="_blank" rel="external">中译版 By @onevcat 及其朋友们</a>):”关于 Objective-C 最佳实践和先进技术的期刊。 由 Chris Eidhof, Daniel Eggert 和 Florian Kugler 成立于柏林。我们成立 objc.io 的目的是针对深入的、跟所有 iOS 和 OS X 开发者相关的技术话题创造一个正式的平台。“</li>
<li><a href="http://www.ioscreator.com/" target="_blank" rel="external">iOSCreator</a>:这类开发指引式教程对于初学者来讲,是直接明了的有效学习资源。推荐者<a href="http://weibo.com/qq184675420" target="_blank" rel="external">@荧星诉语</a></li>
<li><a href="https://iosdevweekly.com/" target="_blank" rel="external">iOS Dev Weekly</a>:收录一周以来 iOS 开发资讯链接,并于周五发布。由 <a href="https://twitter.com/daveverwer" target="_blank" rel="external">Dave Verwer</a> 创办,他是一位 iPhone 和 iPad 开发者以及培训师。</li>
<li><a href="http://www.appcoda.com/" target="_blank" rel="external">Appcoda.com</a>:质量很高的一个 iOS 开发教程站,其中<a href="http://www.appcoda.com/ios-programming-course/" target="_blank" rel="external">iOS Programming Course</a>这个专题很适合刚接触 iOS 开发的新手学习。</li>
<li><a href="https://github.com/tangqiaoboy/iOSBlogCN" target="_blank" rel="external">中文 iOS/Mac 开发博客列表</a>:By <a href="http://weibo.com/tangqiaoboy" target="_blank" rel="external">@唐巧_body</a></li>
<li><a href="http://www.devtalking.com/" target="_blank" rel="external">devtalking.com</a>:高产的中译博客。翻译了官方博客 Swift Blog - Apple Developer,《App Extension Programming Guide》。参与翻译了《Swift Programming Language》等。</li>
<li><a href="http://swift.gg/" target="_blank" rel="external">SwiftGG</a>:一个走心的 Swift 翻译组,由《The Swift Programming Language》中文版翻译团队原班人马组成, 翻译的文章来源于国外的优秀 Swift 网站和博客,且全部获得作者和网站授权。</li>
<li><a href="http://www.jessesquires.com" target="_blank" rel="external">Swift Weekly Brief</a>:“这个博客现在每周会将Swift开源中的重要讨论和提交整理成Open source Swift weekly brief,这对一线开发者尽早了解这门语言的动态情报很有帮助。By <a href="http://weibo.com/cuikang82" target="_blank" rel="external">@崔康总编</a> ”。来源:<a href="http://www.jessesquires.com" target="_blank" rel="external">Jesse Squires</a></li>
<li><p><a href="http://iosdevtips.co" target="_blank" rel="external">iosdevtips.co</a>:iOS Development Tips</p>
</li>
<li><p><strong><a id="recomm_resources"></a>资源合集</strong></p>
<blockquote>
<p>以下是其它开发者社区或 Swift 爱好者整理的有关 Swift 语言学习的资源列表。</p>
</blockquote>
</li>
<li><p><a href="https://github.com/SwiftEducation" target="_blank" rel="external">SwiftEducation</a>:“这是建立在 GitHub 上的一个 Swift 学习资料汇集,包括了有关幻灯和多个练手的应用程序源码。By @极客头条”。的确有不少基础实用的好<a href="https://github.com/SwiftEducation/presentations" target="_blank" rel="external">教程</a>。这对于基础学起的同学有福了。</p>
</li>
<li><a href="https://github.com/hsavit1/Awesome-Swift-Education" target="_blank" rel="external">Awesome-Swift-Education</a>:整理地如此美妙的学习资源,实在让人太欢喜了。</li>
<li><a href="https://github.com/matteocrippa/awesome-swift" target="_blank" rel="external">matteocrippa/awesome-swift</a>:这个版本的 Swift 资源集合内容丰富,分类也不错。作者:<a href="matteocrippa/awesome-swift">Matteo Crippa</a></li>
<li><a href="http://www.csdn.net/article/2015-03-04/2824108-ios-developers-sites/1" target="_blank" rel="external">适合iOS开发者的 15 大网站推荐</a>:的确很全、很主流的国外 iOS 开发者网站。</li>
<li><a href="http://weekly.manong.io/issues/33?ref=swift" target="_blank" rel="external">码农周刊 -《Swift 特刊》</a></li>
<li><a href="http://www.cocoachina.com/bbs/read.php?tid=204512" target="_blank" rel="external">CocoaChina -《Swift 新手入门汇集帖》</a></li>
<li><a href="http://code.csdn.net/news/2820075" target="_blank" rel="external">CSDN_CODE -《Swift 编程语言资料大合集》</a></li>
<li><a href="http://www.infoq.com/cn/news/2014/06/apple-swift-learning-resources" target="_blank" rel="external">InfoQ -《学习苹果 Swift 语言的一些在线资源(英文)》</a></li>
<li><a href="https://github.com/Lax/iOS-Swift-Demos/wiki" target="_blank" rel="external">刘兰涛 -《Swift 学习资源》</a> By <a href="http://weibo.com/u/1653644220" target="_blank" rel="external">@懒桃儿吃桃儿</a></li>
<li><a href="http://www.learnswift.tips/" target="_blank" rel="external">learnswift.tips</a>:国外主流 Swift 学习资源集合。</li>
<li><a href="https://github.com/vsouza/awesome-ios" target="_blank" rel="external">Awesome iOS</a>:一个 iOS 的各类优秀的开源项目集合。真不错!可惜Swift开源项目资源不足。</li>
<li><a href="http://iosdevelopertips.com/" target="_blank" rel="external">iOS Developer Tips</a>:还是有关 iOS 的开发资源及文章合集。</li>
<li><a href="https://github.com/Wolg/awesome-swift" target="_blank" rel="external">Wolg/awesome-swift</a>:一位俄罗斯朋友分类整理的 Swift 资源列表(有持续更新)。</li>
<li><a href="https://github.com/Aufree/trip-to-iOS" target="_blank" rel="external">Aufree/trip-to-iOS</a>:显然作者很用心的做了非常深入的整理。它对于开发者拓展学习范围及开发知识面非常有益。</li>
<li><a href="https://swift.zeef.com/robin.eggenkamp" target="_blank" rel="external">Robin Eggenkamp - Awesome Swift</a>:“一个收集了很多 Swift 开发资源的网站”。</li>
<li><a href="https://github.com/bboyfeiyu/iOS-tech-frontier" target="_blank" rel="external">iOS 开发技术前线</a>:“一个定期翻译、发布国内外iOS优质的技术、开源库、软件架构设计、测试等文章的开源项目”。主要翻译来源 Ray Wenderlich,App Coda,Medium。来源:<a href="http://weibo.com/u/5589212242" target="_blank" rel="external">@开发技术前线</a></li>
<li><a href="http://www.cocoachina.com/ios/20150626/11348.html" target="_blank" rel="external">11个超棒的 iOS 开发学习网站</a>:还算比较主流的归纳。不过,缺了raywenderlich.com 和 ioscreator.com 这两个重量级教程网站实在是不应该啊。</li>
</ul>
<hr>
<h2 id="开发工具"><a href="#开发工具" class="headerlink" title="开发工具"></a><a id="tools"></a>开发工具</h2><h3 id="1-编程工具"><a href="#1-编程工具" class="headerlink" title="1. 编程工具"></a>1. 编程工具</h3><ul>
<li><a href="https://developer.apple.com/swift/resources/" target="_blank" rel="external">Xcode 下载</a>:苹果应用集成开发环境。支持 C/C++, Objective C, Swift 等。不用购买开发者计划,直接下载。</li>
<li><a href="http://macromates.com/" target="_blank" rel="external">Textmate</a>:Mac OS X 上一个可高度自定义的编辑器,尤其在我想做出一个快速改变但又不想等待 Xcode 加载的时候。该工具目前已经<a href="https://github.com/textmate/textmate" target="_blank" rel="external">开源</a></li>
<li><a href="http://mouapp.com/" target="_blank" rel="external">Mou</a>:OS X 上一款 Markdown 的编辑器。非常适用于编写自述文件、变更日志以及其他方面的内容。作者:<a href="http://chenluois.com/" target="_blank" rel="external">罗晨</a></li>
<li><a href="http://www.sublimetext.com/" target="_blank" rel="external">Sublime Text ($)</a>:Mac OS X 上另一款非常受欢迎的轻量级,可高度自定义的编辑器。</li>
<li><a href="http://www.runswiftlang.com/" target="_blank" rel="external">RunSwift</a>:正在犹豫是否入手苹果电脑开始一段 Swift 编程旅程的同学们,或仅仅为了试验一段简单 Swift 代码又懒得打开 Xcode,可以试试这款 Web 版 Swift 编译环境 RunSwift。</li>
<li><a href="http://infinitapps.com/bezel/" target="_blank" rel="external">InfinitApps - Bezel</a>:“嫌 Xcode 6 目前提供的 Watch 模拟器不够直观?Bezel 是一个用于视觉预览 WatchKit 所开发程序效果的小工具,前提是你安装了 xScope 软件(Mac端)或 xScopeMirror(iPhone端)。 By <a href="http://weibo.com/twios" target="_blank" rel="external">@WatchKit开发</a>”</li>
<li><a href="https://github.com/jas/playground" target="_blank" rel="external">Markdown -> Playground</a>:该开源项目可将内含有 Swift 代码的 Markdown 自动转换为 Xcode Playgrounds 文件。喜欢用 Markdown 编辑的同学很激动吧。P.S. 这款工具写于 NodeJS,原因作者有交待。</li>
<li><a href="https://autolayoutconstraints.com" target="_blank" rel="external">iOS/Mac Autolayout Constraints</a>:这个工具不错,很直观,布局时可以省不少工夫。推荐者:<a href="http://weibo.com/qq184675420" target="_blank" rel="external">@荧星诉语</a></li>
<li><a href="https://appscreens.io/yK7cLuBNij" target="_blank" rel="external">在线生成 AppStore 审核用截图</a>:便捷的生产力工具。免费,易操作,可自定义。</li>
</ul>
<h3 id="2-代码管理"><a href="#2-代码管理" class="headerlink" title="2. 代码管理"></a>2. 代码管理</h3><ul>
<li><a href="https://github.com/" target="_blank" rel="external">GitHub</a>:声望日盛的资源分享之地。</li>
<li><a href="https://desktop.github.com/" target="_blank" rel="external">GitHub for Mac</a>:一个设计的非常美观的 git 客户端,不能取代你从命令行获得的所有功能,但使用起来非常简单。</li>
<li><a href="https://gitcafe.com/" target="_blank" rel="external">GitCafe</a>:GitCafe is a source code hosting service based on version control system Git。国内的代码托管服务,基于 Git,值得一提的是最近也推出了和 GitHub Pages 类似的服务 Gitcafe Pages。因为是在国内,所以相比较 GitHub 有速度优势,在网络环境差的情况下也许可以作为 GitHub 的备用。</li>
<li><a href="https://bitbucket.org/" target="_blank" rel="external">Bitbucket</a>:国外的代码托管服务,不同于 GitHub 的是,Bitbucket 可以免费建立 private 项目。</li>
<li><a href="http://git-scm.com/" target="_blank" rel="external">Git</a>:分布式版本控制系统和源码管理系统,其优点是:快和简单易用。对于新手来说,可在此查看免费电子书籍。</li>
</ul>
<h3 id="3-Xcode-插件"><a href="#3-Xcode-插件" class="headerlink" title="3. Xcode 插件"></a>3. Xcode 插件</h3><ul>
<li><a href="http://beta.cocoapods.org/" target="_blank" rel="external">CocoaPods</a>:第三方库的管理利器,允许你简单地把第三方库整合进自己的应用中。对我个人来说,我基本上每个项目都使用 CocoaPods。</li>
<li><a href="https://github.com/kattrali/cocoapods-xcode-plugin" target="_blank" rel="external">CocoaPods Xcode Plugin</a>:一款 Xcode 插件,允许你直接从 Xcode 管理 CocoaPod 依赖。</li>
<li><a href="https://github.com/onevcat/VVDocumenter-Xcode" target="_blank" rel="external">onevcat/VVDocumenter-Xcode</a>:快捷注释 Xcode 插件。By <a href="http://weibo.com/onevcat" target="_blank" rel="external">@onevcat</a></li>
<li><a href="https://github.com/omz/ColorSense-for-Xcode" target="_blank" rel="external">ColorSense</a>:一款显示颜色数值的插件,还可以直接通过系统的ColorPicker来自动生成对应颜色代码</li>
<li><a href="https://github.com/ddapps/DeepIniOS" target="_blank" rel="external">Xcode 优秀插件整理</a>:持续保持整理更新的 Xcode 插件整理 By <a href="https://github.com/ddapps" target="_blank" rel="external">@ddapps</a></li>
<li><a href="https://github.com/CodeEagle/SwiftCodeSnippets" target="_blank" rel="external">CodeEagle/SwiftCodeSnippets</a>:自动下载指定 Xcode Snippet 源的 Xcode Plugin。项目缺省提供 Snippet 代码源 <a href="https://github.com/burczyk/XcodeSwiftSnippets/tree/master/plist" target="_blank" rel="external">burczyk/XcodeSwiftSnippets</a> 。</li>
<li><a href="https://github.com/realm/SwiftLint" target="_blank" rel="external">realm/SwiftLint</a>:Realm 采用 Swift 编写的基于 GitHub’s Swift Style Guide 规则的检查工具。除了命令行运行方式,也提供集成 Xcode 的方法。对于新团队,这样的工具可以自动约束大家遵循编程规范。</li>
<li><a href="http://joeshang.github.io/2015/04/10/fix-xcode-upgrade-plugin-invalid/" target="_blank" rel="external">XCode 升级后插件失效的原理与修复办法</a>:由一条命令引发的分析文章。<a href="http://weibo.com/u/2068840121" target="_blank" rel="external">@_TongJZ</a></li>
<li><a href="https://github.com/feinstruktur/CoPilot" target="_blank" rel="external">feinstruktur/CoPilot</a>:通过此插件,Xcode 可以协同编程了(采用 WebSocket 通讯)。如此强大的“黑工具”,不爱它能行吗。<a href="https://vimeo.com/128713880" target="_blank" rel="external">演示视频</a></li>
</ul>
<h3 id="4-管理工具"><a href="#4-管理工具" class="headerlink" title="4. 管理工具"></a>4. 管理工具</h3><ul>
<li><a href="https://github.com/kylef/swiftenv" target="_blank" rel="external">swiftenv</a>:Swift 版本管理器。类似 rvm(Ruby), nvm(Node.js)。</li>
<li><a href="http://brew.sh/index_zh-cn.html" target="_blank" rel="external">HomeBrew</a>:OS X 上非常出色的包管理工具。</li>
<li><a href="http://panic.com/transmit/" target="_blank" rel="external">Transmit ($)</a>:一个Mac OS X 上 FTP 客户端,有着非常漂亮的用户界面和有用的功能。</li>
</ul>
<h3 id="5-调试工具"><a href="#5-调试工具" class="headerlink" title="5. 调试工具"></a>5. 调试工具</h3><ul>
<li><a href="http://fuckingclangwarnings.com/" target="_blank" rel="external">mattt/fuckingclangwarnings.com</a>:警告与语义对照表。以后再也不用为 Xcode 各种警告纠结啦!By <a href="http://weibo.com/foogry" target="_blank" rel="external">@foogry</a></li>
</ul>
<h3 id="6-设计工具"><a href="#6-设计工具" class="headerlink" title="6. 设计工具"></a>6. 设计工具</h3><ul>
<li><a href="http://www.sketchapp.com/" target="_blank" rel="external">sketch</a>:更适合开发应用的矢量设计工具。通过插件还支持与代码协同工作。推荐书籍:<a href="https://designcode.io/sketch" target="_blank" rel="external">Learn Sketch 3</a></li>
</ul>
<hr>
<p>本文转载自:<a href="https://github.com/ipader/SwiftGuide" target="_blank" rel="external">https://github.com/ipader/SwiftGuide</a></p>
<bl
Kindle越狱安装插件实现PDF重排
http://www.xayoung.cn/2016/03/23/Kindle越狱安装插件实现PDF重排/
2016-03-23T13:59:32.000Z
2016-03-31T12:47:12.000Z
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>Kindle作为阅读的神器,集齐舒服的水墨屏、精美排版的电子书、持久舒适的阅读体验等诸多优点,但是其对PDF尤其是扫描版支持堪忧,阅读体验相对亚马逊官方的电子书简直无法忍受,之前有提到过使用GAE部署KindleEar实现自动推送新闻博客文章,接下来将再进一步,对Kindle进行越狱,实现自动重排PDF。</p>
<hr>
<h2 id="对比图"><a href="#对比图" class="headerlink" title="对比图"></a>对比图</h2><p><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f28a1edaf4j20kj0rftca.jpg" alt="before"></p>
<p><img src="http://ww4.sinaimg.cn/large/5e999b55gw1f28a2lkmj9j20ko0rq426.jpg" alt="after"></p>
<hr>
<h2 id="越狱"><a href="#越狱" class="headerlink" title="越狱"></a>越狱</h2><p>首先下载好文件<br><a href="http://pan.baidu.com/s/1c1x5RJq" target="_blank" rel="external">jb.zip</a><br><a href="http://pan.baidu.com/s/1gdLLhNt" target="_blank" rel="external">JailBreak-1.14.N-FW-5.x-hotfix.zip</a></p>
<h2 id="第一步"><a href="#第一步" class="headerlink" title="第一步"></a>第一步</h2><ul>
<li>解压缩,得到 jb 文件夹,把里面的 jb 文件拷贝到 Kindle根目录下;</li>
<li>从电脑弹出 Kindle,然后点击 Kindle右上角的菜单键,打开“体验版网页浏览器”;</li>
<li>点击地址栏调出键盘,在地址栏中输入网址 <a href="http://kindlefere.com/jb,回车;" target="_blank" rel="external">http://kindlefere.com/jb,回车;</a></li>
<li>在打开的页面中,点击底部的【I Agree】按钮,切换到另外一个页面;</li>
<li>先点击页面下方的链接 Stage1,看到出错页面后点击“返回按钮”返回;</li>
<li>再点击页面下方的链接 Stage2,当看到顶部状态栏出现“Run ;fc-cache in the search bar.”时,点击“搜索按钮”,并输入“;fc-cache”(不带引号,只输入标识为红色的字符,别漏掉分号“;”),回车;</li>
<li>当你看到“Jailbreak succeeded!”的提示信息,即表示操作成功。</li>
</ul>
<h2 id="第二步"><a href="#第二步" class="headerlink" title="第二步"></a>第二步</h2><ul>
<li>解压缩下载到的 ZIP 压缩包 JailBreak-1.14.N-FW-5.x-hotfix.zip,得到一个名为 Update_jailbreak_bridge_1.14.N_install.bin 的文件;</li>
<li>将 bin 文件拷贝到 Kindle 磁盘根目录;</li>
<li>依次在 Kindle 中点击“菜单 —> 设置 —> 菜单 —> 更新您的 Kindle”,等待重启;</li>
<li>重启完毕后 Kindle 应该处于越狱状态了。</li>
</ul>
<hr>
<h2 id="插件"><a href="#插件" class="headerlink" title="插件"></a>插件</h2><hr>
<p>KUAL<br>插件下载(KUAL-v2.6.zip): <a href="http://www.mobileread.com/forums/attachment.php?attachmentid=142287&d=1443189086" target="_blank" rel="external">官方链接</a></p>
<p>安装步骤:</p>
<ul>
<li>将 KUAL-KDK-2.0.azw2 拷贝到 Kindle 的 Documents 文件夹中;</li>
<li>打开 Kindle,即可看到一个名 Kindle LAUNCHER图标。</li>
</ul>
<hr>
<p>MobileRead Package Installer (MRPI) —— 插件安装器</p>
<p>插件下载(kual-mrinstaller-1.6.N.zip):<a href="http://www.mobileread.com/forums/attachment.php?attachmentid=141195&d=1439936860" target="_blank" rel="external">官方下载</a> </p>
<p>安装步骤:</p>
<ul>
<li>将 extensions 和 mrpackages 拷贝到 Kindle 根目录下。</li>
</ul>
<hr>
<p>Koreader —— PDF 重排软件</p>
<p>需要安装 KUAL 及其插件 MRinstaller,再安装 kpvbooklet,最后安装 Koreader。</p>
<p>插件下载(kpvbooklet ):<a href="https://github.com/koreader/kpvbooklet/releases/download/v0.6.2/kindle-kpvbooklet-0.6.2.zip" target="_blank" rel="external">官方下载</a><br>插件下载(Koreader ):<a href="https://github.com/koreader/koreader/releases/download/v2015.12.13-nightly/koreader-kindle-arm-linux-gnueabi-v2015.11-11-g16509e2.zip" target="_blank" rel="external">官方下载</a> </p>
<p>安装步骤:</p>
<p>首先确保安装了 KUAL 及其插件 MRPI;</p>
<ul>
<li>将kpvbooklet文件夹内的 update_kpvbooklet_0.6.2_install.bin 拷贝到 Kindle 里 mrpackages 文件夹中;</li>
<li>点击 Kindle 中的 kindle LAUNCHER,依次点击 Helper -> Install MR Packages;<br>耐心等待 kpvbooklet 安装,直到安装完成后 Kindle 重启完毕;</li>
<li>将Koreader文件夹 extensions 中的内容拷贝到 Kindle 根目录下的 extensions 文件夹中;</li>
<li>将文件夹内的 koreader 文件夹拷贝到 kindle 根目录下,即安装完毕。</li>
</ul>
<hr>
<h2 id="大功告成"><a href="#大功告成" class="headerlink" title="大功告成"></a>大功告成</h2><p><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f28ans3guej20go0m8dgo.jpg" alt="此处输入图片的描述"><br><img src="http://ww3.sinaimg.cn/large/5e999b55gw1f28apzu645j20go0m80u8.jpg" alt="此处输入图片的描述"></p>
<hr>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>Kindle作为阅读的神器,集齐舒服的水墨屏、精美排版的电子书、持久舒适的阅读体验等诸多优点,但是其对PDF尤其是扫描版支持堪忧,阅读体验相
Mac上通过部署KindleEar订阅RSS自动推送到Kindle
http://www.xayoung.cn/2016/03/20/Mac上通过部署KindleEar订阅RSS自动推送到Kindle/
2016-03-20T13:53:06.000Z
2016-03-31T12:46:36.000Z
<h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>每天上下班地铁上的闲暇时间,刚好通过阅读可以填补这一空白。所以最近当即入手了<code>Kindle</code> 499款。众所周知,<code>Kindle</code>的邮件推送是这个产品很亮眼的一个功能,日常除了亚马逊购买电子书、拷贝pdf之外,还希望通过它阅读一些时效性的新闻或者自媒体信息。</p>
<hr>
<h2 id="第三方网站"><a href="#第三方网站" class="headerlink" title="第三方网站"></a>第三方网站</h2><p>Kindle4Rss (<a href="http://kindle4rss.com/" target="_blank" rel="external">http://kindle4rss.com/</a>)<br>经过几天的搜索,发现<code>Kindle4Rss</code>算是比较容易上手的,试用了两天发现效果还行,但是免费用户有一定的限制(免费用户的限制是12个订阅RSS,总共2mb的图片,需手动投递)。<img src="http://ptbsare.org/img/gae%E4%B8%8A%E6%90%AD%E5%BB%BAkindleear%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8rss%E6%8A%93%E5%8F%96%E8%AE%A2%E9%98%85/0.2.png" alt="此处输入图片的描述"></p>
<hr>
<h2 id="GAE搭建KindlEar"><a href="#GAE搭建KindlEar" class="headerlink" title="GAE搭建KindlEar"></a>GAE搭建KindlEar</h2><p>为了实现程序员“懒癌”思维作祟,发现有前辈已经写了一个可以部署到<code>GAE(Google App Engine)</code>上面运行的一个<code>APP</code>,通过<code>python</code>实现网站自动抓取RSS并且自动推送了。它就是<code>KindleEar</code>,目前源代码托管在<a href="https://github.com/cdhigh/KindleEar" target="_blank" rel="external">Github</a>上。<br><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f23nu3kbg1j20qy0hwtc4.jpg" alt="此处输入图片的描述"></p>
<hr>
<h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><p>必备条件:<br>Gmail/Python(2.7)/科学上网<br>由于我的是Mac,自带Python环境,直接跳过</p>
<h2 id="新建APP"><a href="#新建APP" class="headerlink" title="新建APP"></a>新建APP</h2><p>在<a href="https://appengine.google.com/" target="_blank" rel="external">Google App Engine</a>上面新建一个APP,APP名字自定,记下APP的ID。<br><img src="http://ww4.sinaimg.cn/large/5e999b55gw1f23nnsauirj20vn0f90v1.jpg" alt="此处输入图片的描述"></p>
<h2 id="安装Google-App-Engine-for-Python"><a href="#安装Google-App-Engine-for-Python" class="headerlink" title="安装Google App Engine for Python"></a>安装<a href="https://cloud.google.com/appengine/downloads" target="_blank" rel="external">Google App Engine for Python</a></h2><p>下载app,拖到 Applications 文件夹里即可,必须运行一次来安装必要的 App Engine 部署文件。会提示创建一组 symlinks,建议创建以方便未来调用指令。</p>
<h2 id="KindleEar源码"><a href="#KindleEar源码" class="headerlink" title="KindleEar源码"></a>KindleEar源码</h2><p>直接clone</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/cdhigh/KindleEar.git</span><br></pre></td></tr></table></figure>
<p>解压到任意目录</p>
<hr>
<h2 id="软件配置"><a href="#软件配置" class="headerlink" title="软件配置"></a>软件配置</h2><p>打开以下三个文件:app.yaml,module-worker.yaml,config.py。<br>两个 yaml 文件只需要修改第一行,将默认的 kindleear 改为你的 Application ID 即可。<br>config.py 需要修改两个地方:一个是 SRC_EMAIL,请将默认的赋值改为你自己的 gmail 地址;另一个是 DOMAIN,把默认的 kindleear 改为你的 Application ID。软件配置修改完毕。</p>
<hr>
<h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><p>此处根据前辈们的经验,最好不要使用<code>Google App Engine Launcher</code>上传部署,直接命令行上传。<br>cd到源码目录,执行以下命令:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python /usr/local/bin/appcfg.py update app.yaml module-worker.yaml</span><br><span class="line">python /usr/local/bin/appcfg.py update .</span><br></pre></td></tr></table></figure>
<p>上传log无错误后,打开<code>http://Application ID.appspot.com/</code>测试是否能正常访问,根据页面提示填写亚马逊邮件账号,并将我们的Gmail账号加入信任列表。<br><img src="http://ww4.sinaimg.cn/large/5e999b55gw1f23n1sw9jaj20nm0bs0vu.jpg" alt="此处输入图片的描述"><br><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f23nuuvx57j20ni0kmwir.jpg" alt="此处输入图片的描述"><br>再去设置中点击“现在投递”测试kindle能否正常收到推送邮件<br><img src="http://ww3.sinaimg.cn/large/5e999b55gw1f23nyumtyuj20go0m8wht.jpg" alt="此处输入图片的描述"><br><img src="http://ww2.sinaimg.cn/large/5e999b55gw1f23nzi90alj20go0m8jus.jpg" alt="此处输入图片的描述"></p>
<hr>
<h2 id="拓展"><a href="#拓展" class="headerlink" title="拓展"></a>拓展</h2><p>如果对域名不满意,还可以通过DNS转发实现绑定个人域名,导入自己的rss源,还可以自己编写脚本获取图片排版更精致的文章。</p>
<h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>每天上下班地铁上的闲暇时间,刚好通过阅读可以填补这一空白。所以最近当即入手了<code>Kindle</code> 499款。众所周知,<c
iOS UITableviewWrapperView偏移问题
http://www.xayoung.cn/2015/09/22/iOS UITableviewWrapperView偏移问题/
2015-09-22T13:21:05.000Z
2016-03-31T12:45:58.000Z
<h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>在UInavigationController下面使用tableView,使用Autolayout进行约束的时候,发现经常多出或者少64。</p>
<hr>
<h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2><p>查了一下相关的文档和stackoverflow类似问题。可以通过设置视图控制器的这个属性:automaticallyAdjustsScrollViewInsets<br>apple的解释:</p>
<table><br><tr><th>A Boolean value that indicates whether the view controller should automatically adjust its scroll view insets.</th></tr><br><tr><th>The default value of this property is YES, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to NO if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.</th></tr><br></table>
<p>iOS7以下系统,UITableViewCell.superview就是UITableView,但在IOS7中,cell上面还多了一个UITableViewWrapperView,不做iOS7以下的兼容,设置一下这个属性就解决了。</p>
<p><img src="http://ww4.sinaimg.cn/large/5e999b55gw1f25yxsc80xj20r50il40j.jpg" alt="此处输入图片的描述"></p>
<h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>在UInavigationController下面使用tableView,使用Autolayout进行约束的时候,发现经常多出或者少64。<
基于路由器的博客:(三)域名、动态DNS设置
http://www.xayoung.cn/2015/03/30/Breaker固件3/
2015-03-30T10:02:18.000Z
2016-03-22T13:06:18.000Z
<p>安装好博客之后就可以开始通过192.168.1.1:82访问博客了,但是如何让外网也可以访问网站呢?<br>这时候就需要绑定域名和动态DNS了。</p>
<h2 id="注册专属的域名"><a href="#注册专属的域名" class="headerlink" title="注册专属的域名"></a>注册专属的域名</h2><p>(免费的二级域名有很多,比如f3322、花生壳等,这里选用花生壳)<br><img src="http://ww3.sinaimg.cn/large/5e999b55gw1ewi5d6mbhhj20p70cg75o.jpg" alt="此处输入图片的描述"></p>
<h2 id="DNS解析"><a href="#DNS解析" class="headerlink" title="DNS解析"></a>DNS解析</h2><p>可以先手动填写本机的外网ip到记录值处,测试能否ping成功。<br>然后进入路由器动态dns管理界面,将刚刚注册的域名以及用户密码如下图填写。<br><img src="http://ww3.sinaimg.cn/large/5e999b55jw1ewi5hesombj20iw0kzach.jpg" alt="此处输入图片的描述"></p>
<h2 id="端口设置"><a href="#端口设置" class="headerlink" title="端口设置"></a>端口设置</h2><p>进入路由器-网络-防火墙<br>设置入站数据为接受<br><img src="http://ww2.sinaimg.cn/large/5e999b55gw1ewi5kmj1q8j20l90k2jsc.jpg" alt="此处输入图片的描述"></p>
<h2 id="设置端口转发"><a href="#设置端口转发" class="headerlink" title="设置端口转发"></a>设置端口转发</h2><p>此处设置外部端口为82,内部端口为82(上一章设置的端口),在这里也可以设置访问路由器的端口,就能远程访问路由器了。<br><img src="http://ww3.sinaimg.cn/large/5e999b55gw1ewi5p4yxu9j20vj0meaeg.jpg" alt="此处输入图片的描述"></p>
<p>安装好博客之后就可以开始通过192.168.1.1:82访问博客了,但是如何让外网也可以访问网站呢?<br>这时候就需要绑定域名和动态DNS了。</p>
<h2 id="注册专属的域名"><a href="#注册专属的域名" class="headerlink" title
基于路由器的博客:(二)搭建nginx+php+mysql环境
http://www.xayoung.cn/2015/03/25/Breaker固件2/
2015-03-25T09:56:25.000Z
2016-03-22T13:06:09.000Z
<p>上一章已经把HG255D的系统刷为OpenWrt,将环境搭建起来就可以上传博客的安装包了</p>
<h2 id="安装软件"><a href="#安装软件" class="headerlink" title="安装软件"></a>安装软件</h2><p>(我的固件已经将nginx、php编译进去了,这一步只需安装mysql、spawn和shadow相关的软件)<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">opkg update</span><br><span class="line">opkg install block-mount #自动挂载U盘</span><br><span class="line">opkg install mysql-server </span><br><span class="line">opkg install spawn-fcgi zoneinfo-core zoneinfo-asia</span><br><span class="line">opkg install shadow-groupadd shadow-useradd</span><br></pre></td></tr></table></figure></p>
<hr>
<h2 id="创建账户、数据库文件夹等"><a href="#创建账户、数据库文件夹等" class="headerlink" title="创建账户、数据库文件夹等"></a>创建账户、数据库文件夹等</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">groupadd www</span><br><span class="line">useradd -g www www</span><br><span class="line">mkdir /mnt/sda1/web #确保挂载了U盘</span><br><span class="line">chown -R www:www /mnt/sda1/web</span><br><span class="line">mkdir -p /mnt/sda1/data /mnt/sda1/data/mysql /mnt/sda1/data/tmp</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="修改-etc-my-cnf"><a href="#修改-etc-my-cnf" class="headerlink" title="修改/etc/my.cnf"></a>修改/etc/my.cnf</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">datadir = /mnt/sda1/data/mysql/</span><br><span class="line">tmpdir = /mnt/sda1/data/tmp/</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="启动mysql"><a href="#启动mysql" class="headerlink" title="启动mysql"></a>启动mysql</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/etc/init.d/mysqld start</span><br></pre></td></tr></table></figure>
<h2 id="输入如下命令创建mysql的密码(记住账户密码)"><a href="#输入如下命令创建mysql的密码(记住账户密码)" class="headerlink" title="输入如下命令创建mysql的密码(记住账户密码)"></a>输入如下命令创建mysql的密码(记住账户密码)</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/usr/bin/mysqladmin -u root password 123456</span><br></pre></td></tr></table></figure>
<h2 id="登陆数据库"><a href="#登陆数据库" class="headerlink" title="登陆数据库"></a>登陆数据库</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p</span><br></pre></td></tr></table></figure>
<h2 id="连接上mysql-创建数据库(aaaa随意写,记住即可,安装博客时需要填)"><a href="#连接上mysql-创建数据库(aaaa随意写,记住即可,安装博客时需要填)" class="headerlink" title="连接上mysql,创建数据库(aaaa随意写,记住即可,安装博客时需要填)"></a>连接上mysql,创建数据库(aaaa随意写,记住即可,安装博客时需要填)</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">create database aaaa</span><br><span class="line">\g</span><br></pre></td></tr></table></figure>
<h2 id="退出mysql"><a href="#退出mysql" class="headerlink" title="退出mysql"></a>退出mysql</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">quit</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="修改-etc-nginx-nginx-conf"><a href="#修改-etc-nginx-nginx-conf" class="headerlink" title="修改/etc/nginx/nginx.conf"></a>修改/etc/nginx/nginx.conf</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">user www www;</span><br><span class="line">worker_processes 1;</span><br><span class="line">pid /var/run/nginx.pid;</span><br><span class="line">error_log /var/log/nginx_error.log;</span><br><span class="line">events {</span><br><span class="line">use epoll;</span><br><span class="line">worker_connections 1024;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">http {</span><br><span class="line">include mime.types;</span><br><span class="line">default_type application/octet-stream;</span><br><span class="line">sendfile on;</span><br><span class="line">tcp_nopush on;</span><br><span class="line">#keepalive_timeout 0;</span><br><span class="line">keepalive_timeout 65;</span><br><span class="line">gzip on;</span><br><span class="line">access_log off;</span><br><span class="line"></span><br><span class="line">include vhost.conf;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="修改-etc-nginx-fastcgi-params,解决Nginx文件类型错误解析漏洞"><a href="#修改-etc-nginx-fastcgi-params,解决Nginx文件类型错误解析漏洞" class="headerlink" title="修改/etc/nginx/fastcgi_params,解决Nginx文件类型错误解析漏洞"></a>修改/etc/nginx/fastcgi_params,解决Nginx文件类型错误解析漏洞</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">if ($request_filename ~* (.*)\.php) {</span><br><span class="line">set $php_url $1;</span><br><span class="line">}</span><br><span class="line">if (!-e $php_url.php) {</span><br><span class="line">return 403;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">fastcgi_param QUERY_STRING $query_string;</span><br><span class="line">fastcgi_param REQUEST_METHOD $request_method;</span><br><span class="line">fastcgi_param CONTENT_TYPE $content_type;</span><br><span class="line">fastcgi_param CONTENT_LENGTH $content_length;</span><br><span class="line"></span><br><span class="line">fastcgi_param SCRIPT_NAME $fastcgi_script_name;</span><br><span class="line">fastcgi_param REQUEST_URI $request_uri;</span><br><span class="line">fastcgi_param DOCUMENT_URI $document_uri;</span><br><span class="line">fastcgi_param DOCUMENT_ROOT $document_root;</span><br><span class="line">fastcgi_param SERVER_PROTOCOL $server_protocol;</span><br><span class="line"></span><br><span class="line">fastcgi_param GATEWAY_INTERFACE CGI/1.1;</span><br><span class="line">fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;</span><br><span class="line"></span><br><span class="line">fastcgi_param REMOTE_ADDR $remote_addr;</span><br><span class="line">fastcgi_param REMOTE_PORT $remote_port;</span><br><span class="line">fastcgi_param SERVER_ADDR $server_addr;</span><br><span class="line">fastcgi_param SERVER_PORT $server_port;</span><br><span class="line">fastcgi_param SERVER_NAME $server_name;</span><br><span class="line"></span><br><span class="line"># PHP only, required if PHP was built with --enable-force-cgi-redirect</span><br><span class="line">fastcgi_param REDIRECT_STATUS 200;</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="添加-etc-nginx-vhost-conf(端口需要修改成80以外的端口,我这里设置成82)"><a href="#添加-etc-nginx-vhost-conf(端口需要修改成80以外的端口,我这里设置成82)" class="headerlink" title="添加/etc/nginx/vhost.conf(端口需要修改成80以外的端口,我这里设置成82)"></a>添加/etc/nginx/vhost.conf(端口需要修改成80以外的端口,我这里设置成82)</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">server {</span><br><span class="line">listen 82;</span><br><span class="line">server_name localhost;</span><br><span class="line">root /mnt/sda1/web;</span><br><span class="line">index index.html index.htm index.php default.php;</span><br><span class="line">error_page 500 502 503 504 /50x.html;</span><br><span class="line"></span><br><span class="line">location = /50x.html {</span><br><span class="line">root html;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location ~* ^.+\.php(\/.*)*$ {</span><br><span class="line">fastcgi_pass 127.0.0.1:9000;</span><br><span class="line">fastcgi_index index.php;</span><br><span class="line">fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;</span><br><span class="line">include fastcgi_params;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="修改-etc-php-ini"><a href="#修改-etc-php-ini" class="headerlink" title="修改/etc/php.ini"></a>修改/etc/php.ini</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">short_open_tag = on</span><br><span class="line">#doc_root = "/mnt/www" </span><br><span class="line"></span><br><span class="line">extension=ctype.so</span><br><span class="line">extension=curl.so</span><br><span class="line">extension=gd.so</span><br><span class="line">extension=mbstring.so</span><br><span class="line">extension=mcrypt.so</span><br><span class="line">extension=mysql.so</span><br><span class="line">extension=pdo.so</span><br><span class="line">extension=pdo_mysql.so</span><br><span class="line">extension=session.so</span><br><span class="line">extension=sockets.so</span><br><span class="line">extension=tokenizer.so</span><br><span class="line">extension=xml.so</span><br><span class="line"></span><br><span class="line">[Date]</span><br><span class="line">date.timezone = Asia/Shanghai</span><br><span class="line"></span><br><span class="line">[MySQL]</span><br><span class="line">mysql.default_socket = /var/run/mysqld.sock</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="启动spawn-fcgi(如需开机自动运行,可将命令添加到-etc-rc-local)"><a href="#启动spawn-fcgi(如需开机自动运行,可将命令添加到-etc-rc-local)" class="headerlink" title="启动spawn-fcgi(如需开机自动运行,可将命令添加到/etc/rc.local)"></a>启动spawn-fcgi(如需开机自动运行,可将命令添加到/etc/rc.local)</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 2 -f /usr/bin/php-cgi</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="启动nginx"><a href="#启动nginx" class="headerlink" title="启动nginx"></a>启动nginx</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/etc/init.d/nginx enable</span><br><span class="line">/etc/init.d/nginx start</span><br></pre></td></tr></table></figure>
<p>接着就可以上传类似emlog、TypeCho等博客安装程序了</p>
<p>上一章已经把HG255D的系统刷为OpenWrt,将环境搭建起来就可以上传博客的安装包了</p>
<h2 id="安装软件"><a href="#安装软件" class="headerlink" title="安装软件"></a>安装软件</h2><p>(我的固件已经将ng
基于路由器的博客:(一)编译OpenWrt Barrier Breaker固件
http://www.xayoung.cn/2015/03/20/Breaker固件/
2015-03-20T09:48:02.000Z
2016-03-22T13:05:33.000Z
<p>标签:Hardware</p>
<h2 id="编译环境"><a href="#编译环境" class="headerlink" title="编译环境"></a>编译环境</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Ubuntu 14.10 64位虚拟机</span><br></pre></td></tr></table></figure>
<h2 id="安装配置编译所需要的软件包"><a href="#安装配置编译所需要的软件包" class="headerlink" title="安装配置编译所需要的软件包"></a>安装配置编译所需要的软件包</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev gawk gcc-multilib flex git-core gettext</span><br></pre></td></tr></table></figure>
<h2 id="下载OpenWrt-Barrier-Breaker源码,svn-git"><a href="#下载OpenWrt-Barrier-Breaker源码,svn-git" class="headerlink" title="下载OpenWrt Barrier Breaker源码,svn/git"></a>下载OpenWrt Barrier Breaker源码,svn/git</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"> svn co svn://svn.openwrt.org/openwrt/branches/barrier_breaker</span><br><span class="line"></span><br><span class="line">or</span><br><span class="line"></span><br><span class="line"> git clone git://git.openwrt.org/14.07/openwrt.git</span><br></pre></td></tr></table></figure>
<h2 id="更新源"><a href="#更新源" class="headerlink" title="更新源"></a>更新源</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cd barrier_breaker</span><br><span class="line">./scripts/feeds update -a</span><br><span class="line">./scripts/feeds install -a</span><br></pre></td></tr></table></figure>
<h2 id="打开对HG255D的支持"><a href="#打开对HG255D的支持" class="headerlink" title="打开对HG255D的支持"></a>打开对HG255D的支持</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim target/linux/ramips/image/Makefile</span><br></pre></td></tr></table></figure>
<h2 id="将所有HG255D前面的-去掉"><a href="#将所有HG255D前面的-去掉" class="headerlink" title="将所有HG255D前面的#去掉"></a>将所有HG255D前面的#去掉</h2><h2 id="配置make-menuconfig"><a href="#配置make-menuconfig" class="headerlink" title="配置make menuconfig"></a>配置make menuconfig</h2><p>如图<br><img src="http://i1.tietuku.com/4bf0256c0f5a14ca.png" alt="memuconfig1"><br><img src="http://i1.tietuku.com/e6c569043b05f553.png" alt="menuconfig2"><br>选择好功能模块就可以开始编译了<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make V=99</span><br></pre></td></tr></table></figure></p>
<p>历时几个小时不等,注意过程中需要保持网络畅通。</p>
<h2 id="刷机,固件地址"><a href="#刷机,固件地址" class="headerlink" title="刷机,固件地址"></a>刷机,固件地址</h2><pre><code>bin/ramips/openwrt-ramips-rt305x-hg255d-squashfs-sysupgrade.bin
</code></pre>
<p>标签:Hardware</p>
<h2 id="编译环境"><a href="#编译环境" class="headerlink" title="编译环境"></a>编译环境</h2><figure class="highlight plain"><table><tr><td