<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Balloonsys Inc.]]></title>
  <link href="https://linkoubian.github.io/atom.xml" rel="self"/>
  <link href="https://linkoubian.github.io/"/>
  <updated>2019-05-27T22:22:45+08:00</updated>
  <id>https://linkoubian.github.io/</id>
  <author>
    <name><![CDATA[Linkou Bian]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[One Day in Hong Kong]]></title>
    <link href="https://linkoubian.github.io/blog/2019/05/27/one-day-in-hkg/"/>
    <updated>2019-05-27T21:05:13+08:00</updated>
    <id>https://linkoubian.github.io/blog/2019/05/27/one-day-in-hkg</id>
    <content type="html"><![CDATA[<p>上上周四从虹桥飞了趟深圳，周五在平安大学（深圳观澜）培训了一整天，周六从福田口岸去了趟香港、当天回到深圳，周日中午飞回上海。本文主要目的是记录一下办理香港银行账户的过程。</p>

<!--more-->


<h2>准备</h2>

<h3>通行证</h3>

<p>旧的本式通行证已被卡片式的取代了，直接在<a href="http://www.police.sh.cn/crj/">上海出入境</a>网站上预约即可办理。现场直接刷身份证打印申请表、采集出入境证件电子照，然后取号窗口办理。证 80 元，签注一次 15 元，可以扫码支付。</p>

<p>收到取卡短信通知后，去现场可自助取卡，当然也可以选择快递上门。</p>

<h3>预约开户</h3>

<p>因为是周六去香港，预约周六营业的银行网点。招商永隆银行尖沙咀分行（加拿分道 4 号），周六营业时间是上午 9 点到下午 1 点。在线提交开户申请后，会拿到一个诸如 BK1905045960 这样的预约编号。我约的是 12:30 大概 12:15 去的现场。</p>

<h3>开户材料</h3>

<p>只需要身份证、通行证、住址证明，至于网上说的收入证明、工资流水、入境小票等等，统统不需要。住址证明可以采用招行寄送的纸质信用卡账单。</p>

<h3>兑换港币</h3>

<p>开户后直接存入 1 万港币（海关允许携带的现金上限是两万 RMB），这样可以豁免账户管理费（每月 100 HKD）。</p>

<h2>开户</h2>

<p>按照约定时间到达即可，到早了也不会给你提前办理。因为我一上来就亮明是该银行合作券商的客户，所以整个过程没有被「客户面谈（KYC）」，仅仅是核对了下材料。等了十来分钟就拿到了卡片、密码器等，然后去柜台存钱。</p>

<p>网银密码是登录手机 APP 后需要修改的，ATM 取款密码暂时用不到。手机上就可以激活密码器，这个在银证转换登记服务时会用到。</p>

<p>积累的几点经验：</p>

<ol>
<li>营业时间是到下午 1 点，但如果你的业务还没办理完毕，是不会赶你的啦</li>
<li>柜台取款凭借签名，ATM 取款验证密码</li>
<li>开户后的一周会收到支票本，这也解释了为何住址证明是必需的开户材料</li>
<li>跨境汇款，收款银行也是要收费的，如果存在中间行也会收费（而且不便宜）</li>
<li>存入的 1 万港币可以在手机端存为一年定期，会比柜台存定期的利率高一丢丢</li>
</ol>


<h2>港股</h2>

<h3>入金</h3>

<p>在大陆银行卡购汇，然后跨境汇款到香港银行账户。平安银行当天到账，而且手续费减半（25 RMB）、电报费 80 RMB。不过到达永隆银行账户时少了 200 HKD，想必是永隆收了 50、中间行（渣打）收了 150 HKD，下次（如果有下次）改用招行借记卡试试。</p>

<p>从香港银行账户将钱转到证券账户，优先选用银证转换（快&amp;免费）。具体方法及通道，参考券商的官方教程（通常都非常详细）。建议入金的时机选择在该券商的活动期间，通常入 1 万多港币会返现几百块。</p>

<h3>打新</h3>

<p>目前选择的是多账户申购、开盘当天 11 点前卖出的策略。有些券商是以公司名义提交打新申请、有些是提交身份证号的。对于上报身份证的券商，建议只选一家，无论其上报身份证的后几位。</p>

<p>不同券商的费率差别很大，互联网券商通常在获客期间有较大的优惠，不要错过。</p>

<h3>预期</h3>

<p>打新的收益预期，我目前设定在 -15% 到 30% 之间。</p>

<h2>其他</h2>

<p>开完户将近下午 1 点，排队办业务的人还不少，柜台的工作人员看起来也蛮着急的。我离开银行后，直奔尖沙咀码头，花 3.7 港币搭天星小轮到湾仔。然后坐地铁到铜锣湾，在希慎广场诚品书店买了本余英时回忆录（约 100 RMB，好贵）后再坐地铁到中环皇后广场。从中环坐回尖沙咀，逛完星光大道后坐地铁到落马洲回深圳。</p>

<ol>
<li>新办卡片式通行证时，留过指纹。所以，第一次进入香港，也是可以走自助通道的（先刷通行证、再指纹）</li>
<li>返程东铁线是到罗湖的，所以在上水下车等下下一班车到落马洲（关注显示屏）</li>
<li>游客过境旅游票 1 天（落马洲的地铁服务中心，100 HKD）比八达通更适合一日游</li>
<li>电信流量漫游，连接代理服务器太慢，没法使用 Google Maps 等</li>
</ol>


<p>坐在香港地铁上，迎面而来的列车从右手边驶过，真切的感受到和大陆交通规则的差别。但逛街时大量靠右的行人分分钟教会你随大流是多么的必要。</p>

<p>-EOF-</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Review 2018]]></title>
    <link href="https://linkoubian.github.io/blog/2019/01/11/review-2018/"/>
    <updated>2019-01-11T20:38:59+08:00</updated>
    <id>https://linkoubian.github.io/blog/2019/01/11/review-2018</id>
    <content type="html"><![CDATA[<p>2018 年已经结束，离农历新年也不远矣。谨以此文简单回顾下过去一年里的工作、生活等，至少能回答自己时间都去哪儿了。</p>

<!--more-->


<h2>学习</h2>

<p>一如既往，我学习的主要形式是读书。今年读了几本以 1976 年前后数十年时代为背景的传记、回忆录等；技术类的翻过一点但读的并不够细，数量也不足。</p>

<h3>文学</h3>

<h4><a href="http://dangshi.people.com.cn/GB/146570/355070/index.html">邓小平时代</a></h4>

<p>这本书非常适合成年人看，看完后过一年再读一遍效果或许更佳。</p>

<h4><a href="http://www.ruanyifeng.com/blog/2006/05/peter_hessler_oracle_bones.html">甲骨文</a></h4>

<p>陈梦家，总让我想起往事并不如烟里的张伯驹。</p>

<h4><a href="https://www.amazon.com/Life-Death-Shanghai-Cheng-Nien/dp/0802145167/">上海生死劫</a></h4>

<p>作者中学读的南开，大学读的燕京，1930年代留学英国就读于伦敦政治经济学院。未来计划再读一遍作者用英文写的原版。</p>

<p><img src="https://images-na.ssl-images-amazon.com/images/I/511-HeJGHlL._SX329_BO1,204,203,200_.jpg" alt="Life and Death in Shanghai" /></p>

<h4><a href="https://zh.wikipedia.org/wiki/%E9%B8%BF%EF%BC%9A%E4%B8%89%E4%BB%A3%E4%B8%AD%E5%9B%BD%E5%A5%B3%E4%BA%BA%E7%9A%84%E6%95%85%E4%BA%8B">鸿:三代中国女人的故事</a></h4>

<p>通过一个特殊家庭展示了中国从封建社会到新时代的剧变。</p>

<h3>技术</h3>

<h4><a href="https://www.apress.com/us/book/9781484241011">Beginning ARKit for iPhone and iPad</a></h4>

<p>作者在介绍每个案例时都从零开始一步一步的贴代码，真心没必要。不过作为入门教程，快速掌握 ARKit 开发框架还是不错的。</p>

<h4><a href="https://www.bignerdranch.com/books/front-end-web-development/">Front-End Web Development</a></h4>

<p>个人涉猎 Web 端开发技术的第一本技术书，力荐。</p>

<h3>代码</h3>

<p>仅仅读了一两份开源的代码，就不好意思列出来了。这一块 2019 年做些加强，技术的精进还是离不开对优秀代码的深度研读的。</p>

<h2>理财</h2>

<h3>互金</h3>

<p>玩了几年的 P2P 理财，今年算是掉坑里了。现在还有不少钱陷在两个平台里，到期了但债转不出去。除了放宽心，也别无他法，耐心等待吧。总不至于，拉横幅讨债去？人，还是要讲点体面的。</p>

<blockquote><p>文章发出的第二天早上，其中一个车贷平台的债权转让终于成功，本息安全收回。另一个 A 股上市公司全资控股的平台，前景依旧不明朗。</p></blockquote>

<p>在互联网金融备案这事儿尘埃落定前，应该不会再投入。</p>

<h3>股票</h3>

<p>作为股市的新韭菜，市场待我确实不薄，连续中了两次新股。刚进场时的 3200 跌到现在的 2500 点，我还能坦然面对，应该和新股赚的四万块是密不可分的。遥想刚入股市时，跌了五个点，就有只无形的手托着我的爪子去点卖出、割肉。</p>

<p>撇开新股的收益，一年下来亏了七八个点（写作此文时仅亏三个多点），相对于市场的中位数还是很说的过去的啦。</p>

<p>来年继续采用控制单只股的仓位加上网格交易的策略，目前整体仓位 70% 多些，一直按着计划在执行。</p>

<h3>基金</h3>

<p>这一块采用无脑跟投<a href="https://qieman.com/longwin/index">长赢计划</a>的方式，既然对该策略及其主理人选择了信任，就坚信下去，虽然目前亏损 10 多个点。</p>

<p>指数基金，会成为个人长期的一个投资品种。</p>

<h2>工作</h2>

<h3>管理</h3>

<p>上半年转到新成立的部门，负责移动端团队的建设和一期项目的研发。新部门对价值观（无脑加班）的重视程度，若能匀一丢丢到管理水平的提升上，或许这个产品还能走的远一些。很多事情的发展，不是个人能决定的。在一期上线后迅速调整了战场。</p>

<p>每一段经历，都是人生的一笔财富。我有幸参与了公司绝大部分的移动项目，而且很多线上 iOS APP 还是我从零搭建的。</p>

<h3>开发</h3>

<p>今年点亮的个人技能貌似只有 AR。年初产品同事就有规划做个 AR 小工具，年尾在新部门动工并顺利完成。有点遗憾的是，在做 AR 阶段工作汇报时未能按计划将构思的脉络植入到现场领导的脑中。</p>

<p>对既往开发工作成果提炼后申请了四项发明专利，其中三项极有可能给我带来一笔不菲的奖金。</p>

<h3>架构</h3>

<p>年底终于在公司内找到契机，去推动筹谋许久的 Ping An React Native 技术建设及应用实践。早在 2016 年就尝试游说领导，2018 年中在向部门领导汇报移动端技术时也推销过。</p>

<p>好事多磨，本周终于 kick off 了！</p>

<h3>其他</h3>

<p>本周末是我在平安四周年的纪念日，四年里送别一波又一波的同事、连饭搭子都换了好几茬。工作遇到坎坷时，总能看开，想必也是这几年自己心智越发成熟的表现。</p>

<p>多年来不变的是糟糕的情绪管理。只要一来劲，敢把皇帝拉下马。这一点不知道何时才能有实质性的改变，急。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[关于 iOS 私有 API 扫描]]></title>
    <link href="https://linkoubian.github.io/blog/2018/09/11/scan-private-api/"/>
    <updated>2018-09-11T09:23:16+08:00</updated>
    <id>https://linkoubian.github.io/blog/2018/09/11/scan-private-api</id>
    <content type="html"><![CDATA[<p>近期研究了关于私有 API 扫描这个主题。研读了业界现有的相关文章后发现，很多都是简单的摘录，也不对存在的谬误做任何点评。本人在阅读了网易游戏开源的 iOS private api checker 项目后，对如何构建私有 API 库、该项目又是如何识别 APP 中的私有 API、该方案存在哪些问题，一一做了阐述。</p>

<!--more-->


<h2>审核案例</h2>

<ol>
<li><p><a href="http://www.cocoachina.com/bbs/read.php?tid=12514&amp;page=1">自定义方法和私有 API 重名</a></p>

<p>APP 没有被拒绝，但是 Apple 提醒下次更新时修改相关 API 名称。</p>

<p>然而多年前，广为使用的 Three20 里包含和私有 API 重名的<a href="https://stackoverflow.com/questions/1865778/iphone-app-rejected-because-of-three20-non-public-api-lineheight-and-previo">方法</a>，导致很多使用该框架的 APP 审核不通过。</p></li>
<li><p><a href="https://stackoverflow.com/questions/18756906/apple-reject-my-app-because-using-private-api-allowsanyhttpscertificateforhos">使用了非公开方法</a></p>

<p>Apple 发现 APP 使用了非公开的方法 <strong><code>allowsAnyHTTPSCertificateForHost:</code></strong>，拒绝的同时还提供开发者自查的方法。</p></li>
<li><p>未执行到的私有 API 调用</p>

<p>Qzone 中曾自定义接口 <strong><code>_define:</code></strong> 但是并没有调用过，结果也被 Apple 发现并拒绝上架。<code>UITextView</code> 导出的头文件中有该方法。</p></li>
<li><p><a href="https://www.nytimes.com/2017/04/23/technology/travis-kalanick-pushes-uber-and-himself-to-the-precipice.html">Tim Cook 威胁下架 Uber 应用</a></p>

<p>Uber 使用私有 API获取设备的序列号，苹果 CEO 严厉斥责该行为并威胁要下架。</p></li>
</ol>


<h2>调用方式</h2>

<h3>直接调用</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="p">[</span><span class="nb">self</span><span class="p">.</span><span class="n">view</span> <span class="n">recursiveDescription</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>因为私有 API 没有暴露出来，编译会报错。可以添加匿名 <code>Category</code> 声明下私有方法。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@interface</span> <span class="bp">UIView</span><span class="p">()</span>
</span><span class='line'><span class="o">-</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="n">recursiveDescription</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>字符拼接</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="bp">NSArray</span> <span class="o">*</span><span class="n">parts</span> <span class="o">=</span> <span class="l">@[</span><span class="s">@&quot;_priva&quot;</span><span class="p">,</span> <span class="s">@&quot;teMethod&quot;</span><span class="l">]</span><span class="p">;</span>
</span><span class='line'><span class="bp">NSString</span> <span class="o">*</span><span class="n">selectorString</span> <span class="o">=</span> <span class="p">[</span><span class="n">parts</span> <span class="nl">componentsJoinedByString</span><span class="p">:</span><span class="s">@&quot;&quot;</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="nb">self</span> <span class="nl">performSelector</span><span class="p">:</span><span class="n">NSSelectorFromString</span><span class="p">(</span><span class="n">selectorString</span><span class="p">)</span> <span class="nl">withObject</span><span class="p">:</span><span class="nb">nil</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<h3>代码混淆</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="c1">// statusBar</span>
</span><span class='line'><span class="bp">NSData</span> <span class="o">*</span><span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="bp">NSData</span> <span class="nl">dataWithBytes</span><span class="p">:(</span><span class="kt">unsigned</span> <span class="kt">char</span><span class="p">[]){</span><span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x75</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x42</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">}</span> <span class="nl">length</span><span class="p">:</span><span class="mi">9</span><span class="p">];</span>
</span><span class='line'><span class="bp">NSString</span> <span class="o">*</span><span class="n">key</span> <span class="o">=</span> <span class="p">[[</span><span class="bp">NSString</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithData</span><span class="p">:</span><span class="n">data</span> <span class="nl">encoding</span><span class="p">:</span><span class="n">NSASCIIStringEncoding</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<h2>检测方法</h2>

<h3>符号表</h3>

<p>用 <code>nm</code>, <code>otool</code> 等工具导出二进制包的函数符号表，以检查私有 API 的调用。缺点是无法检测字符串拼接方法的私有 API 调用。</p>

<h3>动态扫描</h3>

<p>动态扫描需要应用运行起来，每当调用方法时就判断是否是私有 API，但是效率会很低，而且不能保证代码完全覆盖。</p>

<h3>静态分析</h3>

<p>在对二进制文件反汇编结果的基础上，进行静态分析：</p>

<ol>
<li>找出动态调用 API 方法如 <code>performSelector:</code> ，以及调用对象的类</li>
<li>检查参数，如果参数是拼接方法生成，推导求得拼接的结果</li>
</ol>


<p>如何推导，请阅读加拿大 <code>Laval University</code> 发表的题为 <code>Static Analysis of Binary Code to Isolate Malicious Behaviors</code> 的<a href="https://pdfs.semanticscholar.org/70cd/4cd765313852369a2100301fde45dc09fbd5.pdf">论文</a>。如果拼接字符串由服务端下发，依旧可以避开检查。</p>

<h2>网易方案</h2>

<h3>构建私有 API 库</h3>

<p>从 <code>Github</code> 下载 <a href="https://github.com/NetEaseGame/iOS-private-api-checker">iOS-private-api-checker</a> 后，可使用 WEB 的方式上传一个 <code>IPA</code> 进行扫描。我们可以使用 virtualenv 创建一个虚拟环境，来安装所需的依赖库，以免影响系统级的 Python 环境。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp"># 创建虚拟环境</span>
</span><span class='line'><span class="n">virtualenv</span> <span class="n">venv</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># 启用虚拟环境</span>
</span><span class='line'><span class="p">.</span> <span class="n">venv</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">activate</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># 安装依赖的库</span>
</span><span class='line'><span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">r</span> <span class="n">requirements</span><span class="p">.</span><span class="n">txt</span>
</span><span class='line'>
</span><span class='line'><span class="cp"># 启动监测服务</span>
</span><span class='line'><span class="n">python</span> <span class="n">run_web</span><span class="p">.</span><span class="n">py</span>
</span></code></pre></td></tr></table></div></figure>


<p>工程的 <code>app/templates/main/index_page.html</code> 里介绍了检查的原理：</p>

<ol>
<li>通过 <code>class-dump</code> 导出 <code>Frameworks</code> 及 <code>PrivateFrameworks</code> 的头文件，分别设置为集合 PU 和 PR</li>
<li>通过 Xcode 代码提示的 SQLite 数据库查询出所有的 documented API，设置为集合 DA</li>
<li>那么 PU - DA 为公有 Framework 中的私有 API，设置为 A</li>
<li>PR 为私有 Framework 中的 API，都不能使用。则私有 API 集合 PRAPI = A + PR</li>
<li>使用 <code>class-dump</code> 反编译 ipa 中的 APP 文件，然后和 PRAPI 集合取交集即可获得</li>
</ol>


<p>但是，项目根目录下的 <code>README.md</code> 写道：</p>

<blockquote><p>私有的api ＝ (class-dump Framework下的库生成的头文件中的api - (Framework下的头文件里的api = 有文档的api + 没有文档的api)) + PrivateFramework下的api</p></blockquote>

<p>我第一眼看到这个公式，对其中每一个运算项的含义不是非常肯定，对括号里写上等于号也是有疑问的。另外，这个公式里还提到了 Framework 下的头文件里的 API，而在 index_page.html 中完全没有提到。所以，<strong>建议先无视这个公式</strong>，对 index_page.html 里的文字也不要纠结。</p>

<p>阅读 <code>build_api_db.py</code> 时，看到方法 <code>rebuild_private_api</code> 中的注释里写道：</p>

<blockquote><p>set_E private api<br/>
undocument_api = set_B - set_C<br/>
set_E = set_A - set_C - undocument_api = set_A - set_B<br/>
if include_private_framework: set_E = set_E + set_D</p></blockquote>

<p>单从集合运算的角度看 set_E = set_A - set_C - undocument_api 和 set_A - set_B 能不能划等号？讲道理，应该是 <strong>set_E = set_A - (set_B + set_C)</strong> 吧。这里的 <code>+</code> 是套用原作者的简化写法，指集合的 <code>∪</code> 运算。所以，<strong>建议无视这个注释</strong>。</p>

<p>注释表述的虽有问题，但通读代码发现实际实现的逻辑是没有问题的。现根据 <code>build_api_db.py</code> 及相关的代码所对应的构建私有 API 库的原理做一简要阐述：</p>

<ol>
<li>set_A，表示从系统 Frameworks 目录下所有的 <code>.framework</code> 文件 dump 出的头文件解析出的 API 集合。对应 <code>ios_private.db</code> 中的 <code>framework_dump_apis</code> 表记录。</li>
<li>set_B，表示从系统 Frameworks 目录下所有的 <code>.framework</code> 文件中的头文件解析出的 API 集合。对应 <code>ios_private.db</code> 中的 <code>framework_header_apis</code> 表记录。</li>
<li>set_C，表示从 docSet 中索引文件解析出来的 API 集合。对应 <code>ios_private.db</code> 中的 <code>document_apis</code> 表记录。</li>
<li>set_D，表示从系统 PrivateFrameworks 目录下所有的 <code>.framework</code> 文件 dump 出的头文件解析出的 API 集合。对应 <code>ios_private.db</code> 中的 <code>private_framework_dump_apis</code> 表记录。</li>
<li>set_E，表示私有 API，从 set_A 中识别出的私有 API 对应 <code>framework_private_apis</code> 中的记录，表 <code>private_apis</code> 中的是加上 set_D 的记录。</li>
<li>如果 <code>rebuild_sdk_private_api</code> 函数的第二个参数是 <code>False</code> 则 set_D 不会被加入到 <code>private_apis</code> 表中。</li>
</ol>


<h4>构建集合 A</h4>

<p>在 <code>api_utils.py</code> 中已经封装好了使用 <code>class-dump</code> 导出 <code>.framework</code> 的头文件。所以不需要 <code>DumpFrameworks.pl</code> 这类的外部脚本，而且 <code>DumpFrameworks.pl</code> 生成的头文件目录结构和本项目不吻合。也不需要下载 <a href="http://seriot.ch">Nicolas Seiot</a> 基于 <a href="https://github.com/nst/RuntimeBrowser">RuntimeBrowser</a> 导出的<a href="https://github.com/nst/iOS-Runtime-Headers">头文件</a>。</p>

<p>我们需要做的是，保证目标系统 (比如 8.1) 的模拟器在本机已经安装，并且知道 Frameworks 及 PrivateFrameworks 的路径。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="o">/</span><span class="n">Library</span><span class="o">/</span><span class="n">Developer</span><span class="o">/</span><span class="n">CoreSimulator</span><span class="o">/</span><span class="n">Profiles</span><span class="o">/</span><span class="n">Runtimes</span><span class="o">/</span><span class="n">iOS</span> <span class="mf">8.1</span><span class="p">.</span><span class="n">simruntime</span><span class="o">/</span><span class="n">Contents</span><span class="o">/</span><span class="n">Resources</span><span class="o">/</span><span class="n">RuntimeRoot</span><span class="o">/</span><span class="n">System</span><span class="o">/</span><span class="n">Library</span><span class="o">/</span><span class="n">Frameworks</span>
</span></code></pre></td></tr></table></div></figure>


<p>需要注意的是，上述路径 iOS 和 8.1 之间存在一个空格。这个空格会引起执行 class-dump 的脚本出问题，具体如何修复后面会给出建议。</p>

<p>根据我的实验结果，将上述路径的 8.1 改成 9.3 或者 10.3 即为不同系统下的路径。iOS 11.4 的路径是：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="o">/</span><span class="n">Applications</span><span class="o">/</span><span class="n">Xcode</span><span class="p">.</span><span class="n">app</span><span class="o">/</span><span class="n">Contents</span><span class="o">/</span><span class="n">Developer</span><span class="o">/</span><span class="n">Platforms</span><span class="o">/</span><span class="n">iPhoneOS</span><span class="p">.</span><span class="n">platform</span><span class="o">/</span><span class="n">Developer</span><span class="o">/</span><span class="n">Library</span><span class="o">/</span><span class="n">CoreSimulator</span><span class="o">/</span><span class="n">Profiles</span><span class="o">/</span><span class="n">Runtimes</span><span class="o">/</span><span class="n">iOS</span><span class="p">.</span><span class="n">simruntime</span><span class="o">/</span><span class="n">Contents</span><span class="o">/</span><span class="n">Resources</span><span class="o">/</span><span class="n">RuntimeRoot</span><span class="o">/</span><span class="n">System</span><span class="o">/</span><span class="n">Library</span><span class="o">/</span><span class="n">Frameworks</span>
</span></code></pre></td></tr></table></div></figure>


<p>我们不需要记住这些路径，需要的是掌握获取路径的方法，用 find 命令也是 OK 的。</p>

<h4>构建集合 B</h4>

<p>Frameworks 路径已经在构建集合 A 的部分介绍过，<code>api_utils.py</code> 中 <code>framework_header_apis</code> 方法就是用于构建 Frameworks 目录下所有的 <code>.framework</code> 文件中的头文件解析出的 API 集合。看出和集合 A 的区别了吧？一个是直接处理 <code>.framework</code> 中包含的头文件，一个是从 <code>.framework</code> 中的 Mach-O 文件导出对应的头文件。</p>

<p>构建集合 A/D 其实就比构建集合 B 多一步，即 dump 的过程。这也是为何在 dump 时，导出头文件的目录和系统 framework 文件内部结构一致，这样使得接下来的构建集合过程的代码可以通用。</p>

<h4>构建集合 C</h4>

<p>生成 documented API 集合的主要障碍在于，本机缺乏 docSet。本文写于 2018 年 9 月初，我的工作机上只有 Xcode 9，而新版本的 Xcode 已经使用新的文档格式并直接集成在 Xcode 中。其实苹果官方提供了一个包含各版本文档链接等信息的 <a href="https://developer.apple.com/library/downloads/docset-index.dvtdownloadableindex">XML</a>，将该 XML 下载到本地即可从中找到 iOS 8.1 等的文档下载链接。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c"># 各版本 iOS docSet 的元信息</span>
</span><span class='line'>https://developer.apple.com/library/downloads/docset-index.dvtdownloadableindex
</span><span class='line'>
</span><span class='line'><span class="c"># iOS 8.1 docSet</span>
</span><span class='line'>https://devimages-cdn.apple.com/docsets/20141020/031-07735-A.dmg
</span><span class='line'>
</span><span class='line'><span class="c"># iOS 9.3.5 docSet</span>
</span><span class='line'>https://devimages-cdn.apple.com/docsets/20160321/031-52212-A.dmg
</span></code></pre></td></tr></table></div></figure>


<p>安装下载下来的 dmg 后，在 Mac OS 根目录下便出现 docSet 文件了，你可以随意挪位置。docSet 内部的 Contents/Resources/docSet.dsidx 是我们获得集合 C 的数据源。</p>

<p>本人习惯使用 SQLPro for SQLite 工具查看 sqlite 数据库文件，将 docSet.dsidx 重命名为 docSet.sqlite 即可双击打开。其中 <code>ZTOKENTYPE</code> 表中的 <strong>func</strong>，<strong>instm</strong>，<strong>clm</strong>，<strong>intfm</strong>，<strong>intfcm</strong> 五种类型是我们要关注的：</p>

<ol>
<li>func 表示全局 C 函数</li>
<li>instm 表示实例方法 instance method</li>
<li>clm 表示类方法 class method</li>
<li>intfm 表示协议方法，- 开头</li>
<li>intfcm 表示协议方法，+ 开头</li>
</ol>


<blockquote><p>凭感觉猜测 intf 是 interface 的缩写，interface 即 OOP 的接口而不是 Obj-C 定义类的那个 interface</p></blockquote>

<p>至于最新版 iOS 的 documented API 怎么获得，本人没有研究。既然 Dash 的作者能生成 Apple API Reference 那理论上讲应该是可以生成 dsidx 文件的。记录有些许价值的 Dash Release Notes 作为日后研究的线索：</p>

<p>&ldquo;Xcode 8 doesn’t come with docsets anymore and that means Dash won’t automatically support the iOS 10, macOS 10.12, watchOS 3 and tvOS 10 docs. I’m working on a version of Dash that supports the new docs and will release an update as soon as possible.&rdquo; &ndash; <a href="https://blog.kapeli.com/dash-xcode-8-and-macos-sierra">Jun 14th, 2016</a></p>

<p>&ldquo;Apple API Reference Support. Apple has new API docs. You can use them in Dash by installing the Apple API Reference docset.&rdquo; &ndash; <a href="https://blog.kapeli.com/dash-3-dot-3">Jul 2nd, 2016</a></p>

<p>&ldquo;<strong>The Apple API Reference docset now reads the docs from within Xcode 8</strong>. This reduces disk space usage while also allowing me to modify &amp; improve the docs at display-time. Thanks a lot to the Xcode team at Apple for helping me understand the new documentation format!&rdquo; &ndash; <a href="https://blog.kapeli.com/dash-3-dot-4">Oct 25th, 2016</a></p>

<h4>构建集合 D</h4>

<p>同构建集合 A，路径的 Frameworks 改成 PrivateFrameworks 即可：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 8.1.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/
</span></code></pre></td></tr></table></div></figure>


<h4>构建集合 E</h4>

<p>以 set_A 为处理对象：</p>

<ol>
<li>所有以 <code>_</code> 开头的方法，全部加到 set_E 中；</li>
<li>其他 API，如果不在 set_B 也不在 set_C 中，则加到 set_E 中</li>
<li>在不在 set_B / set_C 中的比较基准是 api_name，class_name，sdk 三个值</li>
<li>步骤 3 是基于 db 查询来实现的</li>
</ol>


<h4>代码缺陷</h4>

<ol>
<li><p>build_api_db.py 中  rebuild_sdk_private_api(sdk_version, False)，需改成 True</p></li>
<li><p>build_api_db.py 中  <code>if include_private_framework</code> 之后应该是把 private_framework_apis 插入到数据表中，而不是 <code>framework_dump_private_apis</code></p></li>
<li><p>api/api_utils.py 中 <code>all_headers_path += iterate_dir(framework, "", os.path.join(framework_folder, header_path))</code> 应该改成 <code>all_headers_path += iterate_dir(framework, "", header_path)</code></p></li>
<li><p>db/dsidx_dbs.py 中 sql = balabala 需要确认 dsidx 文件中五种 TOKEN 类型对应的 ID</p>

<p>比如我从 Apple 下载下来的 8.1 docSet 对应相同 <code>ZTOKENTYPE</code> 的 ID 不是 (<strong>3,9,12,13,16</strong>) 而是 (<strong>11,13,1,8,19</strong>)。</p>

<p>如果你是从百度网盘等地方直接下载别人的 ios_private.db，请打开这个 db 检查下 document_apis 表中的数据真的都是 API 么。</p>

<p>另，原作者写 (3,9,12,13,16)  是因为当时 iOS 7.0 docSet 里确实是这几个 ID，这一点我通过往前翻 <a href="https://github.com/NetEaseGame/iOS-private-api-checker/commit/c2b14cc4788ad8e8a8bd2ef1ffac5877251204b2">commit</a> 记录得到了确认。所以灵活一点的写法是根据 <code>ZTYPENAME</code> 筛选数据。</p></li>
<li><p>dump/class_dump_utils.py 中 <code>ret = subprocess.call(cmd.split())</code> 健壮性不够</p>

<p>我在 Xcode 9 安装 iOS 8.1 模拟器后看到 Frameworks 路径是带空格的，经过 split 就会导致路径被拆分成两段。改成 ret = subprocess.call([class_dump_path, &lsquo;-H&rsquo;, frame_path, &lsquo;-o&rsquo;, out_path]) 应该就可以规避该问题。</p></li>
</ol>


<h3>扫描私有 API</h3>

<h4>主要逻辑</h4>

<p>阅读 <code>iOS_private.py</code> 梳理出识别 APP 中私有 API 的主要逻辑如下：</p>

<ol>
<li>基于 <code>strings</code> 工具从 Mach-O 文件导出字符串，按空格拆解得到集合1</li>
<li>使用 <code>otool -L</code> 从 Mach-O 文件获得用到的 Frameworks 及 PrivateFrameworks 列表</li>
<li>基于 <code>class-dump</code> 从 Mach-O 文件导出的头文件信息，解析出类名变量名集合2、方法集合3</li>
<li>集合4 = 集合1 - 集合2（比较基准是 api_name）</li>
<li>表 <code>framework_private_apis</code> 中按 api_name, class_name 分组得到类名方法名组合的集合5</li>
<li>对集合5 和集合4 按 api_name 匹配，得到集中6</li>
<li>集合6 和集合 3 按 api_name, class_name 匹配，得到最终的私有 API 集合</li>
</ol>


<p>步骤2 的结果可以作为步骤5 的部分条件。白名单表 <code>whitelist</code> 里的数据，会从结果集中排除，对应到代码逻辑上也是在步骤5 被过滤掉。</p>

<h4>代码缺陷</h4>

<p>因上述步骤6 中是按 api_name, class_name 的组合做匹配条件的，故原始代码的 SQL 语句中 group by 不仅要有 api_name 还应该加上 class_name 这个字端。</p>

<h3>改进建议</h3>

<p>直接使用网易方案大概率是发现不了私有 API 的。检测逻辑只考虑了 api_name, class_name 全匹配，局限性太大。</p>

<ol>
<li><p>在私有 API 数据库的建设上，TSRC 实验室的做法是进一步增加条件，比如一些纯小写字母的 API，大多是一些 C 函数，再过滤掉一批</p></li>
<li><p>在扫描算法的设计上，如果步骤5 只 group by api_name，步骤6 只匹配 api_name，同时在源代码中存在 <code>@selector(XXX)</code> 这样的字符串，基本可以认定该 api_name 为私有 API</p></li>
<li><p>对于静态拼接或者加解密的 API，可以通过动态 hook 的方式进行识别，但也存在一些局限性</p></li>
<li>加入 <code>prefs:</code> 及 <code>App-Prefs:</code> 协议的扫描</li>
</ol>


<h2>验证特定 API</h2>

<p>苹果审核提出使用了不该用的某某 API，那么我们势必要支持筛查该 API 用在何处，是我们的 APP 还是第三方 SDK 中。在代码工程根目录，执行：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>find . -type f <span class="p">|</span> grep <span class="s2">&quot;.a&quot;</span> <span class="p">|</span> grep -v <span class="s2">&quot;.app&quot;</span> <span class="p">|</span> xargs grep advertisingIdentifier
</span></code></pre></td></tr></table></div></figure>


<h2>遗留主题</h2>

<p>在研读网易游戏的开源方案时，对于 iOS 10+ 如何构建 documented API 数据集这个问题直接跳了过去，后续可进一步调研。</p>

<h2>参考资料</h2>

<p>[ 1 ] Arming Lee. 腾讯 Qzone 工程师. <a href="https://github.com/mrmign/iOS-private-api-scanner/blob/master/iOS-api-scan.md">iOS私有API扫描工作总结</a>. 2014~2015<br/>
[ 2 ] 刘笑江. 腾讯 WeRead 工程师. <a href="http://davidlau.me/2017/08/23/ios-private-api-detection/">iOS 私有 API 调用检测机制探讨</a>. 2017.08.23<br/>
[ 3 ] 郑文明. <a href="https://blog.csdn.net/wenmingzheng/article/details/50475671">iOS状态栏操作</a>. 2016.01.07<br/>
[ 4 ] KFAaron. <a href="https://www.jianshu.com/p/6484ac07c513">导出系统库的头文件</a>. 2016.05.18<br/>
[ 5 ] Friedrich Markgraf. <a href="https://gist.github.com/fzwo/01d62cebd21032683d87f51d094575d3">LegacyDocsets</a>. 2017.05.11<br/>
[ 6 ] 林桠泉. 腾讯安全应急响应中心. <a href="https://security.tencent.com/index.php/blog/msg/105">浅谈 iOS 应用安全自动化审计</a>. 2016.06.23<br/>
[ 7 ] Rumin Shah. <a href="https://stackoverflow.com/a/31779425">How do I check where my app is using IDFA</a>. 2015.08.03<br/>
[ 8 ] Zuik. <a href="https://zuikyo.github.io/2016/10/10/%E7%A7%81%E6%9C%89API-iOS10%20openURL%E6%96%B9%E6%B3%95%E8%B7%B3%E8%BD%AC%E5%88%B0%E8%AE%BE%E7%BD%AE%E7%95%8C%E9%9D%A2%E5%A4%B1%E6%95%88%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/">使用私有 API 跳转到设置界面</a>. 2016.10.10</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十九期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/05/19/tech-notes-49/"/>
    <updated>2017-05-19T23:30:11+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/05/19/tech-notes-49</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 iPhone 用户忠诚度、RAC 中 weakify 这样的宏是如何定义的、基于 section name 在数据段存取数据、移动端开发之路在何方等。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://www.macrumors.com/2017/05/17/iphone-92-percent-loyalty-rate-survey/">iPhone Scores 92% Loyalty Rate in Recent Survey Ahead of iPhone 8</a> By Joe Rossignol</h4>

<p>本文介绍了摩根斯坦利做的一项调查，92% 的现有 iPhone 用户有兴趣在接下来的一年内购买新的 iPhone。相比于一年前类似调查的 86% 忠诚度，形势喜人！</p>

<h2>开发</h2>

<h4>1) <a href="http://ziecho.com/post/ios/2016-08-04">剖析 RAC 中的 @weakify、@strongify</a> By 郑梓毅</h4>

<p>RAC 中的这个 weakify 版本脱胎于 libextobjc 项目。如果想自己实现一个简化版（只接收一个参数），可以参考 Arek Holko 的<a href="http://holko.pl/2015/05/31/weakify-strongify/">文章</a>。</p>

<h4>2) <a href="https://lpd-ios.github.io/2017/03/06/iOS-BeeHive/">解耦框架 BeeHive</a> By 于德志</h4>

<p>BeeHive 是阿里去年开源的一个 iOS APP 模块化框架。文中介绍的基于 Annotation 的标记实现方案，很不错。我参考实现了一个将好房 APP 的 ViewController 和页面 URL 映射在一起的宏。</p>

<h2>工具</h2>

<h4>1) <a href="http://blog.playstone.org/blog/2017/05/15/imate-for-ios-development/">iMate</a> By Lei Guo</h4>

<p>这是一个 iOS 开发辅助软件，查看 App 产生的文件，也可以快速将 Archive / Build 等文件删除。总的来说，类似之前推荐过的 SimPholders。</p>

<h2>其他</h2>

<h4>1) <a href="http://limboy.me/essay/2017/05/12/mobile-dev-way-out.html">移动端开发路在何方</a> By 李忠</h4>

<p>最近一段时间，移动端开发好像不像以前那么吃香了，招的人少了，要求更高了，给人一种感觉：这个行业是不是不行了？这个行业没出问题，只是更加理性了。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十八期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/05/10/tech-notes-48/"/>
    <updated>2017-05-10T09:31:00+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/05/10/tech-notes-48</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 Apple Watch 相关应用的发展趋势、Swift 异常手段的适用场景、基于 Target / Action 以及 Runtime 的组件化方案，以及与人相处时的一种 delta file 实践。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://appleinsider.com/articles/17/05/01/major-apps-abandoning-apple-watch-including-google-maps-amazon-ebay">Major apps abandoning Apple Watch</a> By Neil Hughes</h4>

<p>第二季度财报会议上，库克表示 Apple Watch、AirPods 和 Beats 产品的销量收入现在已经是财富 500 强公司的规模。不过，不少大型主流 APP 正在移除对 Apple Watch 的支持。</p>

<h4>2) <a href="http://www.cnbc.com/2017/05/09/apple-acquires-beddit-sleep-tracking-app.html">Apple has acquired a sleep-tracking app</a> By Christina Farr</h4>

<p>近期苹果买下了好几款 APP，比如 Workflow。本周又收下了名为 Beddit 的睡眠追踪应用及相关设备。</p>

<h2>开发</h2>

<h4>1) <a href="https://medium.com/@johnsundell/picking-the-right-way-of-failing-in-swift-e89125a6b5b5">Picking the right way of failing in Swift</a> By John Sundell</h4>

<p>本文针对 Swift 的多种异常处理手段做了介绍，分别适用于何种场景。</p>

<h4>2) <a href="http://www.jianshu.com/p/0d3db4422954">Swift 性能相关</a> By Damon Wong</h4>

<p>为什么说 Swift 相比较于 Objective-C 会更加快 ？为什么在编译 Swift 的时候这么慢 ？如何更优雅的去写 Swift ？可以听听本文作者的介绍。</p>

<h4>3) <a href="https://casatwy.com/modulization_in_action.html">基于 CTMediator 的组件化方案</a> By 田伟宇</h4>

<p>本周精读了这种基于 Target / Action 以及 Runtime 的组件化方案，思路确实非常棒！</p>

<h2>工具</h2>

<h4>1) <a href="https://www.visualstudio.com/vs/">Visual Studio for Mac</a></h4>

<p>微软继推出 VS Code 后，又发布了 Mac 版的 Visual Studio，支持 Xamarin 和 .NET Core 开发移动应用和网页等。</p>

<h2>其他</h2>

<h4>1) <a href="https://medium.com/@livlab/dont-work-with-psychopaths-b1a848914455">别与精神病患者共事</a> By Livia Labate</h4>

<p>这种同事并非医学上的精神病患者，而是善于玩弄权术、爱撒谎、自负的人。他们评价别人是根据别人的行为，评价自己是根据自己的动机。</p>

<p>文中提到一种实践，叫 the Delta File：自己创建一个秘密的只有自己才能看到的文档，记录下你的同事、上司表现出的让你很反感的行为；将来你处于他们那个位子了，对比 the Delta file 中你所记录的行为，你会怎么做？他们当时那些行为是合理的吗？</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十七期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/05/02/tech-notes-47/"/>
    <updated>2017-05-02T19:13:31+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/05/02/tech-notes-47</id>
    <content type="html"><![CDATA[<p>本期周报主要包括如何为 React Native 开发配置 VS Code 插件以提高生产力、RN 在 Glow 的实践、Uber 的百名 iOS 工程师使用 Swift 重新架构移动应用的经验等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://wallstreetcn.com/articles/3007744">苹果的现金储备</a> By Wall street CN</h4>

<p>苹果拥有的 2570 亿美元现金储备中，有 1480 亿美元投资了企业债，530 亿美元投资了美国政府国债，210 亿美元投资了抵押债券和资产担保债权。</p>

<h2>开发</h2>

<h4>1) <a href="http://tech.glowing.com/cn/react-native-at-glow/">React Native 在 Glow 的实践</a> By Allen Hsu</h4>

<p>本文记录了 React Native 在 Glow 的实践经验，并主要从 iOS 角度展开一些细节实现。</p>

<h4>2) <a href="https://www.skilled.io/u/swiftsummit/swift-with-a-hundred-engineers">Swift with a hundred engineers</a> By Tuomas Artman</h4>

<p>Uber 的 iOS App 拥有 5k 个文件，共 50 万行代码。为了提高构建速度，拆分出 70 多个组件。为了不影响启动时间，在 build 后把各 framework 中的文件合在一起。</p>

<h2>工具</h2>

<h4>1) <a href="http://matthewpalmer.net/vanilla/">Vanilla-hide Mac Menu bar icons</a> By Matthew Palmer</h4>

<p>这是一款将 Mac 菜单栏的一部分工具图标收起来的免费小工具。喜欢 Bartender 但不愿付费的朋友可以尝试下。</p>

<h4>2) <a href="http://www.jianshu.com/p/caa802ee055b">为 React Native 开发准备的 VS Code 插件</a> By 顾浩鑫</h4>

<p>本文详细介绍了如何为 React Native 开发配置 VSCode 各种插件以提高生产力。</p>

<h2>其他</h2>

<h4>1) <a href="https://stackoverflow.blog/2017/04/27/how-to-talk-about-yourself-in-an-interview/">How to Talk About Yourself in an Interview</a> By Nick Larsen</h4>

<p>不只是面试，在很多社交场合都需要介绍自己，介绍自己做过的事，要会讲故事、让人有兴趣听下去。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十六期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/04/24/tech-notes-46/"/>
    <updated>2017-04-24T00:49:22+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/04/24/tech-notes-46</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 App Store 佣金规则变更、iOS 中图片的解压缩过程、基于 React Native 高仿美团客户端、Appium 入门介绍等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://affiliate.itunes.apple.com/resources/documentation/getting-started/">App Store Affiliate Program</a></h4>

<p>从 5 月 1 号开始，苹果将实行新的佣金规则，所有跟 App 相关的消费行为（比如购买应用、应用内购）将会降至 2.5%，其它类型的内容（音乐、电影、书、电视剧）返利比例则保持 7% 不变。</p>

<h2>开发</h2>

<h4>1) <a href="http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/">谈谈 iOS 中图片的解压缩</a> By 雷纯锋</h4>

<p>图片解压缩的过程其实就是将图片的二进制数据转换成像素数据的过程。了解这些知识，将有助于我们更好地处理图片，管理好它们所占用的内存。</p>

<h4>2) <a href="https://github.com/huanxsd/MeiTuan">基于 React Native 高仿美团客户端</a> By Daniel</h4>

<p>作者曾在百度工作四年，写了六年 Objective-C 代码。主要实现了美团的四个一级页面（团购、附近、订单、我的），以及部分二级页面（团购详情、Web 页面）。</p>

<h2>工具</h2>

<h4>1) <a href="https://github.com/jkpang/PPRows">PPRows for Mac</a> By jkpang</h4>

<p>在 Mac 上计算你写了多少行代码的一款小工具。</p>

<h4>2) <a href="http://www.jianshu.com/p/3932a1c24b93">Appium 从入门到原理</a> By bestswifter</h4>

<p>本文主要会基于一些开源代码和个人实践，对 iOS 端的自动化测试原理做一个简单介绍。</p>

<h2>其他</h2>

<h4>1) <a href="https://61.life/price-tag-summary/amp/">Price Tag 半年总结</a> By Liu Yi</h4>

<p>作者之前和微博干过口水仗，关于 Affiliate link 的事情。我也是从这个新闻才开始了解到 App Store 联盟计划这么个东西的。</p>

<h2>@end</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十五期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/04/21/tech-notes-45/"/>
    <updated>2017-04-21T13:46:19+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/04/21/tech-notes-45</id>
    <content type="html"><![CDATA[<p>本期周报主要包括苹果对微信关闭赞赏的回应、天弘基金移动 App 架构演化、携程无线持续交付平台建设等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://tech.sina.com.cn/mobile/n/n/2017-04-20/doc-ifyepsch1830968.shtml">苹果回应微信关闭赞赏</a> By 新浪科技</h4>

<p>苹果公司这份声明虽然简单但含义明确：赞赏功能并非是苹果逼停的。微信本可以像其他开发者一样，选择App内购方式给公众号运营者；App Store 生态对所有开发者的要求均是一样的。</p>

<h2>开发</h2>

<h4>1) <a href="http://blog.csdn.net/yaoyu/article/details/70184539">天弘基金移动 App 客户端架构优化之路</a> By 姚宇</h4>

<p>天弘·爱理财在前端后端使用的阿里蚂蚁金融云平台。第一个 iOS 版本是在传统的MVC的架构基础上封装了一个网络服务层构建而成。从 2.4 版本开始逐步重构采用 MVVM + 分层架构模式解耦。</p>

<h4>2) <a href="https://skyline75489.github.io/post/2015-8-14_ios_static_dynamic_framework_learning.html">iOS 静态库，动态库与 Framework</a> By Chester Liu</h4>

<p>去年 11 月我总结过在好房移动架构团队做 Framework 开发中的一些经验。本文作者对静态库、动态库、Framework 等基础概念作了介绍。</p>

<h2>工具</h2>

<h4>1) <a href="https://blog.dianqk.org/2017/02/28/use-danger/">Danger</a> By DianQK</h4>

<p>在 Code Review 时，我们可能经常要去检查各种事情，有时我们会忘记，而 Danger 可以友好地完成。其配置非常简单，很容易集成到现有 CI 中。</p>

<h4>2) <a href="http://mp.weixin.qq.com/s/6kf1x0wV1XpH3ycHKCBA7Q">携程无线持续交付平台</a> By 刘李丰</h4>

<p>本文从集成、测试、发布、运营四个子平台来展开分享携程是如何一步步打造无线持续交付平台的。</p>

<h2>其他</h2>

<h4>1) <a href="http://robertheaton.com/2014/03/27/how-does-https-actually-work">How does HTTPS actually work</a> By Rob Heaton</h4>

<p>讲得不算很深的科普文章一篇。看懂后，你就会明白公司下发的标装机多不安全了吧。即使是 HTTPS 请求的内容，也被监控得体无完肤！</p>

<h2>@end</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十四期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/04/15/tech-notes-44/"/>
    <updated>2017-04-15T10:53:56+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/04/15/tech-notes-44</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 Uber 外卖业务使用 React Native 过程中的权衡、手机 QQ Hybrid 的架构如何优化演进、微软在 RN 基础上推出的跨平台框架等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://www.bloomberg.com/amp/news/articles/2017-04-14/apple-gets-dmv-approval-to-test-self-driving-cars-in-california">Apple Said to Near Road Tests of Self-Driving Car Software</a> By Mark Gurman</h4>

<p>苹果已经获得加州的许可，可以在该州测试无人驾驶汽车。</p>

<h2>开发</h2>

<h4>1) <a href="https://eng.uber.com/ubereats-react-native/">Powering UberEATS with React Native</a> By Chris Lewis</h4>

<p>Uber 基于 React Native 技术构建的 Restaurant Dashboard 应用为送餐业务 UberEATS 提供支持。本文介绍了决定使用 React Native，以及确保为餐厅提供可靠、稳健的用户体验过程中所进行的权衡和考虑。</p>

<h4>2) <a href="http://mp.weixin.qq.com/s?__biz=MjM5MDE0Mjc4MA==&amp;mid=2650995689&amp;idx=1&amp;sn=4f77f121345004ae6e18f4b945e46f8e">手机 QQ Hybrid 的架构演进</a> By 涂强</h4>

<p>随着前端开发的兴起，QQ也逐渐演变为Web与原生终端混合的开发模式。QQ 团队除了采用动态 CDN、后台渲染等全栈手段优化体验，也构建了围绕速度、成功率、页面异常等维度的监控体系来保障服务质量。</p>

<h2>工具</h2>

<h4>1) <a href="https://github.com/Microsoft/reactxp">React XP</a> By Microsoft</h4>

<p>微软 Skype 团队开源的跨平台框架, 目前支持 web (React JS), iOS (React Native), Android (React Native) and Windows UWP (React Native) 等平台。</p>

<h4>2) <a href="http://thebugcode.github.io/ios-continous-integration-choosing-a-build-server-and-tooling/">iOS Continous Integration</a> By The Code Bug</h4>

<p>本文对比了 Xcode Server, Jenkins, Travis 以及 fastlane 等多种持续集成工具。</p>

<h2>其他</h2>

<h4>1) <a href="https://hackernoon.com/education-of-a-programmer-aaecf2d35312">Education of a Programmer</a> By Terry Crowley</h4>

<p>作者在微软服役 21 年离职后写就的长文，其中有句话很受欢迎：</p>

<blockquote><p>The deepest learning happens when you struggle with truly hard problems.</p></blockquote>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十三期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/04/07/tech-notes-43/"/>
    <updated>2017-04-07T14:20:58+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/04/07/tech-notes-43</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 Mac Pro 产品线的最新消息、JavaScriptCore 的方方面面、MVC/MVP/MVVM 架构的思路与优缺点、Instagram 的 React Native 实践等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://daringfireball.net/2017/04/the_mac_pro_lives">苹果产品更新</a> By John Gruber</h4>

<p>苹果资深副总裁 Phil Schiller 透露，新 Mac Pro 将采用模块化程度更高、扩展性更强的设计，与之配套的专业显示器也在计划中，明年发布。</p>

<h2>开发</h2>

<h4>1) <a href="http://www.jianshu.com/p/3f5dc8042dfc">深入浅出 JavaScriptCore</a></h4>

<p>本篇文章是作者基于一次组内分享整理而成，包含 Objective-C 与 JavaScript 交互、内存管理、多线程等方面的内容。</p>

<h4>2) <a href="http://www.jianshu.com/p/eedbc820d40a">杂谈: MVC/MVP/MVVM</a></h4>

<p>本文为回答一位朋友关于 MVC/MVP/MVVM 架构方面的疑问所写，旨在介绍 iOS 下这三种架构的设计思路以及各自的优缺点。</p>

<h2>工具</h2>

<h4>1) <a href="https://engineering.instagram.com/react-native-at-instagram-dd828a9a90c7">Instagram 的 React Native 之路</a> By Martin Bigio</h4>

<p>来自 Facebook 的 Instagram 终于来强势支持了一把 React Native。快速迭代、代码复用、减少人力，这么多优点是否值得你去学习甚至在公司项目中引入 React Native 呢？</p>

<h4>2) <a href="https://mp.weixin.qq.com/s/W9jC0W_b7xSWjqfFv7N5Bg">Protocol Buffers</a> By 陶文</h4>

<p>Google 的 Protocol Buffers 在数据编码的效率上似乎被神化了，一直流传性能是 JSON 等本文格式 5 倍以上，本文通过代码测试来比较 JSON 与 PB 具体的性能差别到底是多少。</p>

<h2>其他</h2>

<h4>1) <a href="https://www.raywenderlich.com/158026/introducing-rxswift-reactive-programming-swift">Reactive Programming with Swift</a> By raywenderlich.com</h4>

<p>刚出的一本关于 RxSwift 的技术书籍，Ray 家出品。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十二期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/03/23/tech-notes-42/"/>
    <updated>2017-03-23T08:53:14+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/03/23/tech-notes-42</id>
    <content type="html"><![CDATA[<p>本期周报主要包括苹果产品更新摘要、基于 CollectionView 实现循环滚动的方案、网易的组件化实践、以及一位小米前员工的财务告白等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) 苹果产品更新</h4>

<p>苹果推出红色 iPhone；iPad Air 2 退休，代之以 A9 芯片的新 9.7 寸 iPad；iPhone SE 和 iPad mini 4 的存储也有变化；还更新了 Apple Watch 表带。</p>

<h2>开发</h2>

<h4>1) <a href="https://adoptioncurve.net/archives/2013/07/building-a-circular-gallery-with-a-uicollectionview/">Building a Infinitely-Scrolling Gallery With a UICollectionView</a> By Tim Duckett</h4>

<p>本文提供了支持广告图的循环滚动方案，如果你没有亲手写过而只是用别人的组件，很可能忽视了其中的玄机。</p>

<h4>2) <a href="http://www.jianshu.com/p/196f66d31543">iOS 组件化实践方案</a> By philon</h4>

<p>网易的 iOS 工程师在参考同行的讨论和之前的 LDBusBundle 方案基础上，提炼出了一个适合中小型应用的 LDBusMediator 中间件。</p>

<h2>工具</h2>

<h4>1) <a href="https://github.com/ink-spot/UPCarouselFlowLayout">UPCarouselFlowLayout</a> By Paul Ulric</h4>

<p>我实现新版二手房首页的轮播图效果，很大程度的参考了作者的布局代码。</p>

<h4>2) <a href="http://tool.lu">在线工具</a></h4>

<p>包含正则表达式测试工具、useragent 分析、时间戳转换&hellip;</p>

<h2>其他</h2>

<h4>1) <a href="http://mp.weixin.qq.com/s/fNZdQxx1C_DF3tw25hEt5Q">一位小米前员工的财务告白</a> By 曲哲</h4>

<p>并不是每个人都有赶上时代与公司风口的洞察力，或者是运气。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十一期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/03/13/tech-notes-41/"/>
    <updated>2017-03-13T09:14:10+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/03/13/tech-notes-41</id>
    <content type="html"><![CDATA[<p>本期周报主要包括如何高效添加圆角效果，线程同步相关的知识点、问答式掌握 HTTPS 基本概念，以及 iOS App 签名的原理等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://www.zdziarski.com/blog/?p=7016#aplo">苹果将知名安全专家 Jonathan Zdziarski 招至麾下</a></h4>

<p>如题。用 Jonathan 自己的话来说，跟一群有共同语言的人一同来捍卫用户隐私是一件关涉到良知的事情。</p>

<h2>开发</h2>

<h4>1) <a href="http://www.jianshu.com/p/f970872fdc22">iOS 高效添加圆角效果</a> By  bestswifter</h4>

<p>设置 masksToBounds 会导致离屏渲染，但 iOS 9 只在设置圆角的视图够多时才反应出性能问题。主要的优化方法是用 Core Graphic API 生成一个 UIImage 再插入到 UIView 的子视图中，对于 UIImageView 则是直接将其 Image 裁剪成圆角。</p>

<h4>2) <a href="http://www.dreamingwish.com/article/the-ios-multithreaded-programming-guide-4-thread-synchronization.html">iOS 线程同步</a> By Dreamingwish</h4>

<p>synchronized 最慢，OSSpinLock 最快。OSpinlock 效率奇高主要原因是，并没有进入系统 kernel，使用它可以节省系统调用和上下文切换，如果临界区的执行时间过长则不建议使用。</p>

<h2>工具</h2>

<h4>1) <a href="http://fullstack.blog/2017/03/12/%E4%B9%9D%E4%B8%AA%E9%97%AE%E9%A2%98%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%86%9F%E6%82%89HTTPS/">九个问题从入门到熟悉 HTTPS</a> By bestswifter</h4>

<p>作者 95 年的，就职于百度。对 HTTPS 的理解程度远超我身边的绝大部分同事。</p>

<h4>2) <a href="https://github.com/buunguyen/octotree">octotree</a> By Buu Nguyen</h4>

<p>平常浏览 Github 时，常常需要在代码目录里切来切去，非常麻烦。安装此浏览器插件后，省时省心。</p>

<h2>其他</h2>

<h4>1) <a href="http://blog.cnbang.net/tech/3386/">iOS App 签名的原理</a> By 陈振焯</h4>

<p>iOS 签名机制挺复杂，各种证书，Provisioning Profile，entitlements，CertificateSigningRequest，p12，AppID，概念一堆，也很容易出错，本文尝试从原理出发，一步步推出为什么会有这么多概念，希望能有助于理解 iOS App 签名的原理和流程。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第四十期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/03/11/tech-notes-40/"/>
    <updated>2017-03-11T09:46:40+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/03/11/tech-notes-40</id>
    <content type="html"><![CDATA[<p>本期周报主要包括苹果对 JSPatch / Rollout.io 使用者的警告、基于 HTTP/2 的全新 APNs 协议、IGListKit 使用教程、美团外卖前端团队使用 RN 的实践回顾等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://blog.cnbang.net/internet/3374/">A warning from Apple</a></h4>

<p>苹果给开发者发的一封邮件激起了千层浪，使用 JSPatch 的同学得注意了。还好我给公司设计并开发的 PAHotfix 是去年上线的，否则 KPI 可能要归零。</p>

<h2>开发</h2>

<h4>1) <a href="https://github.com/ChenYilong/iOS9AdaptationTips/blob/master/%E5%9F%BA%E4%BA%8EHTTP2%E7%9A%84%E5%85%A8%E6%96%B0APNs%E5%8D%8F%E8%AE%AE/%E5%9F%BA%E4%BA%8EHTTP2%E7%9A%84%E5%85%A8%E6%96%B0APNs%E5%8D%8F%E8%AE%AE.md">基于 HTTP/2 的全新 APNs 协议</a> By Elon Chan</h4>

<p>其中最大的变化就是基于了 HTTP/2 协议，采用了长连接设计，并提供 HTTP/2 PING 心跳包功能检测、维持当前 APNs 连接，解决了老 APNs 无法维持连接的问题。</p>

<h4>2) <a href="https://www.raywenderlich.com/147162/iglistkit-tutorial-better-uicollectionviews">IGListKit Tutorial: Better UICollectionViews</a> By Ryan Nystrom</h4>

<p>本文介绍了 Instagram 开源的 IGListKit 如何使用。一月份的<a href="http://balloonsys.com/blog/2017/01/13/tech-notes-35/">周报</a>里提到过一篇从 UITableView 迁移到 IGListKit 的文章，不知你看了没有？</p>

<h2>工具</h2>

<h4>1) <a href="https://kiteapp.co">Kite Compositor</a></h4>

<p>一个做动画及原型的工具，有人评价说：犹如 Sketch 遇上 After Effects 遇上 Keynote 呢。</p>

<h2>其他</h2>

<h4>1) <a href="http://mp.weixin.qq.com/s?__biz=MzI1NzYwNjU2Mw==&amp;mid=2247483685&amp;idx=1&amp;sn=6e6109b134cb2421bd688f87605ee361">React Native 一年实践回顾</a> By 大雄</h4>

<p>组内对于 React Native 的实践已经快一年了，我们组主要负责的是美团外卖 M 端的前端业务。本文将总结和回顾一个纯 WEB 前端团队使用 React Native 完成一个应用的整个过程。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第三十九期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/03/03/tech-notes-39/"/>
    <updated>2017-03-03T11:02:56+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/03/03/tech-notes-39</id>
    <content type="html"><![CDATA[<p>本期周报主要包括瑞银及凯基证券分析师的预测、iOS 10 nano_free 崩溃问题的解决方案、美团点评前端无痕埋点实践、Twitter 开源的 TIP 图片框架等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://www.businessinsider.com/ubs-apple-1000-engineers-ar-2017-2">瑞银: 苹果有上千名工程师在以色列研发 AR</a> By Hannah Roberts</h4>

<p>据 Business Insider 援引瑞士银行的一份研究报告称，分析师 Steven Milunovich 表示，苹果的下一个重大产品创新将与 AR 技术有关。</p>

<h4>2) <a href="https://www.macx.cn/thread-2198592-1-1.html">凯基证券：今年所有新 iPhone 都支持 Lightning 快充</a> By 郭明池</h4>

<p>根据凯基证券分析师郭明池的预测，苹果今年将要发布的三款 iPhone，包括旗舰级 OLED iPhone 8 仍然都会配备 Lightning 接口。不同的是，苹果今年会为 Lightning 接口加入快速充电功能。</p>

<h2>开发</h2>

<h4>1) <a href="https://mp.weixin.qq.com/s/hnwj24xqrtOhcjEt_TaQ9w">聊聊苹果的 Bug - iOS 10 nano_free Crash</a> By 张三华</h4>

<p>很多开发者在 iOS 10 上遇到了一类堆栈为 nano_free 字样的 Crash，也有很多人向 Bugly 客服反馈遇到了这类问题，但并没有好的解决方案。正当大家都束手无策的时候，微信强大的技术团队针对这类Crash进行了深度研究，并提出了一个解决方案。</p>

<h4>2) <a href="http://tech.meituan.com/mt-mobile-analytics-practice.html">美团点评前端无痕埋点实践</a> By 富强 朝旭 吴凯</h4>

<p>为了解决前端埋点的准确性、及时性、开发效率等问题，业内各家公司从不同角度，提出了多种技术方案。美团在原有代码埋点方案的基础上，演化出了一套轻量的、声明式的前端埋点方案，并且在动态埋点、无痕埋点等方向做了进一步的探索和实践。</p>

<h2>工具</h2>

<h4>1) <a href="https://blog.twitter.com/2017/introducing-twitter-image-pipeline-ios-framework-for-open-source">Twitter Image Pipeline iOS framework</a> By Nolan O'Brien</h4>

<p>Twitter 开源的 TIP 框架用于图片的加载与缓存，据称已内部迭代两年。其 Android 团队采用的是 Facebook 开源的 fresco 框架。</p>

<h2>其他</h2>

<h4>1) <a href="http://blog.cnbang.net/tech/3354/">iOS 开发技术栈与进阶</a> By 陈振焯</h4>

<p>最近有一些开发朋友问我应该怎样提升自己的能力，回想起来做了这么久 iOS 开发，我也有过那种『让我做一个功能实现个需求我会做，但接下来怎样提高我不知道。』的时期，这里尝试列一下 iOS 开发的相关技术，再说说在学习进阶上我的一些想法。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第三十八期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/02/24/tech-notes-38/"/>
    <updated>2017-02-24T11:44:36+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/02/24/tech-notes-38</id>
    <content type="html"><![CDATA[<p>本期周报主要包括苹果收购面部识别创业公司、iOS A/B Test 方案探索、去哪儿 React Native 应用实践分享等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://www.timesofisrael.com/apple-buys-israels-facial-recognition-firm-realface-report/">Apple buys Israel’s facial recognition firm RealFace</a> By Shoshanna Solomon</h4>

<p>根据以色列周报的报道，苹果用数百万美金收购了一家以色列的面部识别创业公司 Realface。该公司曾发布过一款名为 Pickeez 的应用，它能帮助用户在多个社交平台中找出用户的最佳照片。</p>

<h2>开发</h2>

<h4>1) <a href="http://www.jianshu.com/p/7b4667cde80b">教你如何从0到1实现组件化架构</a> By 袁峥</h4>

<p>文章罗列的主要是组件化架构中 Cocoapods 如何用，对于组件化的架构设计本身并没有涉及。</p>

<h4>2) <a href="http://blog.flight.dev.qunar.com/2017/01/09/ios-abtest-explore/">iOS A/B Test 方案探索</a> By 李剑飞</h4>

<p>近期团队做了很多 AB Test 的业务需求，在这种需求日益见多的情况下，我们不得不提升我们的代码组织方式，以适应或更好的在此类需求上维护我们的代码。本文主要阐述了业务团队在做 AB Test 的一些想法和思路。</p>

<h2>工具</h2>

<h4>1) Launchpad 页面按住 Option</h4>

<p>这是 macOS 出现删除应用按钮的最快捷方式了吧？</p>

<h4>2) <a href="https://atom.io">Atom</a></h4>

<p>之前一直在用 Sublime，现在逐渐换成 Atom 了。最近在读 BNR 出品的 Front-End Web Development 一书，配置了 emmet / autocomplete-paths / linter 等插件后 Atom 算是把利器。</p>

<h2>其他</h2>

<h4>1) <a href="http://mp.weixin.qq.com/s/ARWJDxSB2wJehxgoydtFQw">Qunar React Native 大规模应用实践</a> By 殷文昭</h4>

<p>Qunar React Native 是去哪儿网基于 React Native 定制的一套框架，让 RN 用起来更方便快捷，2016 年 3 月上线后已在公司内部大规模应用。透过 QRN 的大规模实践我们可以看到如何更好地去使用 RN。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第三十七期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/02/13/tech-notes-37/"/>
    <updated>2017-02-13T17:22:58+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/02/13/tech-notes-37</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 App Store 点评功能的新玩法、沃尔玛的 React Native 实践分享、iOS 中 HTTPS 证书验证浅析等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://daringfireball.net/2017/01/new_app_store_review_features">Additional Details on the New App Store Review Features</a> By John Gruber</h4>

<p>iOS 10.3 和 macOS 10.12.4 开始，每个 app 每年只能发三次「求评价」弹窗，用户点评不必离开 app，可以一键关闭所有求点评弹窗，开发者可以直接回复用户的评价。</p>

<h2>开发</h2>

<h4>1) <a href="https://medium.com/walmartlabs/react-native-at-walmartlabs-cdd140589560">沃尔玛的 React Native 实践</a> By Matt Bresnan</h4>

<p>最近，美国零售巨头沃尔玛将它们的官方 App 从 Hybrid 转向了 React Native，获得了非常不错的结果，来看看他们是怎么做的。</p>

<p>PS: Walmart App 背后原来有数百名工程师啊！！！</p>

<h4>2) <a href="https://mp.weixin.qq.com/s/-fLLTtip509K6pNOTkflPQ">iOS 中 HTTPS 证书验证浅析</a> By 李晴</h4>

<p>本文的目的：一是简要分析下对服务器身份验证的完整握手过程，二是证书链的验证，三是探索下 iOS 中原生库 NSURLConnection 或 NSURLSession 如何支持实现 https。</p>

<h2>工具</h2>

<h4>1) <a href="http://www.jianshu.com/p/ad2e37e741bb">细聊 Cocoapods 与 Xcode 工程配置</a> By 张星宇</h4>

<p>对我最有用的信息是：通过 ar -x 解包 .a 文件，再对解出来的 __.SYMDEF SORTED 内容分析发现，其中没有 Category 的目标文件信息，或许这就是静态库中含有 Category 时为何需要专门配置 other linker flag 选项。</p>

<p>作者虽是学生，但思路清晰，很不错的。</p>

<h2>其他</h2>

<h4>1) <a href="https://www.phodal.com/blog/how-to-write-a-resume/">一份优秀的程序员简历是什么样的</a> By 黄峰达</h4>

<p>今年的行情虽然没有去年火热，但是你仍应该拾掇拾掇一下你的简历，万一机会来了呢？</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第三十六期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/01/20/tech-notes-36/"/>
    <updated>2017-01-20T10:18:04+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/01/20/tech-notes-36</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 iOS 应用崩溃自动修复、数据统计无埋点技术、仿网易云音乐导航栏的技术实现等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://www.macrumors.com/2017/01/19/new-ipads-second-half-of-2017/">New iPads Might Not Launch Until Sometime in the Second Half of 2017</a> By Mitchel Broussard</h4>

<p>供应链消息称，苹果将会在今年的下半年对外发布、销售三款新平板电脑。新推出的 9.7 英寸将是廉价版本，主要针对教育市场。</p>

<h2>开发</h2>

<h4>1) <a href="https://neyoufan.github.io/2017/01/13/ios/BayMax_HTSafetyGuard/">iOS APP 运行时 Crash 自动修复系统</a> By 陶泽宇</h4>

<p>关于 app 运行时的 crash，我们是不是可以做的更多？是否可以做到实时抓取 app 运行时产生的 crash，然后直接自动修复它，从而不让 app crash 呢？</p>

<h4>2) <a href="http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&amp;mid=2651112803&amp;idx=1&amp;sn=061e10ff89c15f893511688f9c7864c2">数据统计无埋点技术</a> By 唐星</h4>

<p>本文介绍百分点如何由原来的手动写代码的埋点，发展出不需要写代码的无埋点技术。也介绍了实践中遇到的一些问题和解决方法。</p>

<h2>工具</h2>

<h4>1) <a href="https://github.com/rickytan/RTRootNavigationController">RTRootNavigationController</a> By Ricky Tan</h4>

<p>现在应用的导航栏的颜色不再是单一颜色，还有些需要隐藏 navigationBar 的需求。该项目实现了开发部分提到的网易云音乐导航栏的效果。</p>

<h4>2) <a href="http://microedition.biz/simMagnifier/index.html">simMagnifier</a> By Microedition</h4>

<p>类似于之前推荐过的 SimPholders 工具。除了访问模拟器应用沙盒，还能访问 Core Data 数据文件等。</p>

<h2>其他</h2>

<h4>1) <a href="http://merowing.info/2017/01/seniority/">Seniority</a> By Krzysztof Zabłocki</h4>

<p>资深工程师何以为资深，都需要哪些基本素养？很不错的一篇文章，以作者梳理的各项标准对照自己，提升自己的 Soft Skills，岂不快哉。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第三十五期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/01/13/tech-notes-35/"/>
    <updated>2017-01-13T09:14:13+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/01/13/tech-notes-35</id>
    <content type="html"><![CDATA[<p>本期周报主要包括 Swift 项目负责人变更、IGListKit 的应用实践、throttle 释疑、常用 iOS / Mac 软件推荐清单等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170109/030063.html">苹果 Swift 语言创始人离职</a> By Chris Lattner</h4>

<p>Chris Lattner 在邮件里说对 Swift 项目的发展没有影响，自己依旧会是该项目的积极贡献者。</p>

<h2>开发</h2>

<h4>1) <a href="https://medium.com/cocoaacademymag/iglistkit-migrating-an-uitableview-to-iglistkitcollectionview-65a30cf9bac9">Migrating an UITableView to IGListCollectionView</a> By Rodrigo Cavalcante</h4>

<p>本文介绍了如何从 UITableView 迁移到 Instagram 开源的 IGListCollectionView 方案。</p>

<h4>2) <a href="http://mrpeak.cn/blog/ios-throttle/">iOS 编程中 throttle 那些事</a> By MrPeak</h4>

<p>读完此文，你便会理解为何多张图片上传使用多个请求比放在一个请求的好处，你也会理解 AFN 源码中 Request Serializer 设计 throttleBandwidthWithPacketSize:delay: 这个方法的背后考量。</p>

<h4>3) <a href="http://www.jianshu.com/p/c7efbc283480">iOS Crash 问题排名</a></h4>

<p>作者总结了 5 大 crash 问题，解决了这 5 大 crash 问题，基本上你的 app 就相对健壮许多。其余的崩溃问题就需要具体问题具体分析了。</p>

<h2>工具</h2>

<h4>1) <a href="http://balloonsys.com/blog/2017/01/07/my-favourite-apps/">一位 iOS 开发工程师的常用软件</a> By Linkou Bian</h4>

<p>本文罗列了我在 iOS 及 macOS 上常用的约四十个软件。其中很多工具之前都有推荐，此次做了个小结。</p>

<h4>2) <a href="https://kobiton.com">移动云测试平台 Kobiton</a> By Kobiton</h4>

<p>使用 Chrome 试用了下该服务，提供 24 台 Android 设备及 28 台 iOS 设备供测试 APP。测试期间的操作会记录在 Session 日志里，对应时刻的屏幕也可自动截图保存。自动化测试方面支持 Appium 和 Selenium 框架，目前我没有进一步尝试。</p>

<h2>其他</h2>

<h4>1) <a href="https://techcrunch.com/2017/01/08/wtf-is-a-funding-round/">WTF is a funding round?</a> By Katie Roof</h4>

<p>经常在 TechCrunch 上看到某某公司融资数千万、估值几个亿。本文解释了啥是融资、啥是估值、为啥不贷款、N 轮融资是啥意思、巨额融资算是创业成功吗等。</p>

<p>@end</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[我常用的软件]]></title>
    <link href="https://linkoubian.github.io/blog/2017/01/07/my-favourite-apps/"/>
    <updated>2017-01-07T23:20:01+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/01/07/my-favourite-apps</id>
    <content type="html"><![CDATA[<p>本文罗列了我在 iOS 及 macOS 上常用的约四十个软件。</p>

<!--more-->


<h2>iOS</h2>

<h3>1. Tweetbot</h3>

<p>官方客户端其实挺好的，但是广告实在太多太不吸引我（如果像 YouTube 视频广告的水准，我完全可以接受的）。但 Tweetbot 对 RT 的显示效果没有官方的赞。</p>

<h3>2. Moke</h3>

<p>微博官方客户端同样的广告太多太低劣，Moke 的制作水准相当高。</p>

<h3>3. Spotify</h3>

<p>非常棒的音乐播放软件，特别是长按在专辑之间滑动，可以快速预览（准确的说应该是预听）。</p>

<h3>4. Alipay</h3>

<p>同事一起吃饭，互相转账用用；去小店买买东西，也会扫扫二维码支付。</p>

<h3>5. WeChat</h3>

<p>和老婆孩子视频；去小店买买东西，也会扫扫二维码支付。</p>

<h3>6. 商业周刊</h3>

<p>一百来块钱可以看一年专享文章，但是 APP 的制作水准大不如前，推送频率也很讨厌。</p>

<h3>7. Surge</h3>

<p>上网必备工具，用起来确实方便。</p>

<h3>8. Colorful Pro</h3>

<p>天气应用竟然能在 App Store 里独立一栏，一直不大能理解。选择这款应用是因为对下雨的时间段有较为细致的播报。</p>

<h3>9. Next</h3>

<p>记录每天的消费，月底向老婆报账。</p>

<h3>10. YouTube</h3>

<p>自从发现了几个很赞的频道后，YouTube 成了我的主要娱乐平台。</p>

<h3>11. 大众点评</h3>

<p>改版之后，质感的确提升很多。周末叫个外卖啥的，都喜欢用点评。</p>

<h3>12. Kindle</h3>

<p>地铁或者临睡前，这些不适合 Kindle（硬件）的时候可以用 Kindle 这个 APP。缺点是阅读位置同步难得会正确一次。</p>

<h3>13. LinkedIn</h3>

<p>用来查看公司新来的领导是啥背景。</p>

<h3>14. Drafts</h3>

<p>随手记录一些零碎的文字，比如个人理财策略啥的。</p>

<h2>macOS</h2>

<h3>1. Sublime Text</h3>

<p>首选的文本（包括代码）编辑器，用了很多年。</p>

<h3>2. PDFExpert</h3>

<p>之所以在 Mac 上选择 PDF 格式的技术文档来阅读，而不是 ePub 或 azw 之类的，完全是因为 PDFExpert 太棒了。你可以在文档上直接写写画画，做做笔记。</p>

<h3>3. iA Writer</h3>

<p>首先的 MarkDown 编辑器。一直没有买新版，因为足够用了。</p>

<h3>4. ReadKit</h3>

<p>RSS 客户端，配合 Feedly 用起来还是不错的。</p>

<h3>5. iTerm</h3>

<p>我使用的是 ZSH 而不是默认的 BSH，配置和插件管理由 On My Zsh 负责，其中主题是用的 <a href="https://github.com/oskarkrawczyk/honukai-iterm-zsh">Honukai</a>。</p>

<h3>6. Surge</h3>

<p>上网必备工具，用起来确实方便。</p>

<h3>7. SimPholders</h3>

<p>查看模拟器里的 APP 沙盒位置。</p>

<h3>8. SourceTree</h3>

<p>管理 Git 工程。</p>

<h3>9. Dash</h3>

<p>虽然 Dash 的源代码可能没有那么优雅，但这个软件确实提供了方便。至少我打开 API 文档的概率提高了很多。</p>

<h3>10. Evernote</h3>

<p>虽然 Evernote 在走下坡路，但还没有找到合适的替代品。</p>

<h3>11. Spotify</h3>

<p>为了在公司网络下正常使用，我特地写过一篇<a href="http://balloonsys.com/blog/2016/12/27/spotify-proxy-on-mac/">文章</a>。如果想屏蔽广告，可以看看 <a href="https://www.reddit.com/r/Piracy/comments/4kn6rq/comprehensive_guide_to_blocking_ads_on_spotify/">reddit</a> 上的讨论。</p>

<h3>12. Charles</h3>

<p>挂代理，抓包，看 APP 的 API 接口。</p>

<h3>13. Omnigraffle</h3>

<p>画流程图的首选。</p>

<h3>14. Paw</h3>

<p>最好的 API 测试工具。</p>

<h3>15. SQLPro for SQLite</h3>

<p>在 Mac 上查看 SQLite。</p>

<h3>16. Reveal</h3>

<p>Hack 别人的 APP 或者分析 UI 的设计时，不可或缺的利器。</p>

<h3>17. Sequal Pro</h3>

<p>免费的 MySQL 客户端。</p>

<h3>18. Ummy Video Downloader</h3>

<p>当在 YouTube 上看到不错的视频，想下载下来怎么办？使用 Ummy 出的这个小程序即可，就是 20 刀有点贵。</p>

<h3>19. AirServer</h3>

<p>iPhone 镜像到 Mac 端的 AirServer，这样即使没有专门的连接线也可以在投影仪上演示 APP 的功能。</p>

<h3>20. Movist</h3>

<p>支持的视频格式比较全面。</p>

<h3>21. CleanMyMac</h3>

<p>虽然可以直接把软件拖到回收站，但一些相关的配置文件还是残留在系统里的。使用 CleanMyMac 能够干净的清理不必要的文件。</p>

<h3>22. Sketch</h3>

<p>本来是想用 Sketch 作应用设计的，但全职从事 iOS 开发后几乎没有做过个人产品。</p>

<h3>23. Sip</h3>

<p>屏幕颜色吸取器。</p>

<h3>24. The Unarchiver</h3>

<p>免费好用的解压缩软件。</p>

<h3>25. VMware Fusion</h3>

<p>Mac 上使用 Windows 或 CentOS 或 &hellip;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[平安好房iOS开发团队技术周报（第三十四期）]]></title>
    <link href="https://linkoubian.github.io/blog/2017/01/06/tech-notes-34/"/>
    <updated>2017-01-06T16:44:39+08:00</updated>
    <id>https://linkoubian.github.io/blog/2017/01/06/tech-notes-34</id>
    <content type="html"><![CDATA[<p>本期周报主要包括苹果 2017 新年大促消息、微信 Mars 之 xlog 使用、APP 引导页的设计、Youtube 视频下载工具、常见算法的分析与实现等内容。</p>

<!--more-->


<h2>资讯</h2>

<h4>1) <a href="http://www.apple.com/cn/shop/gifts/new-year-offer">苹果 2017 新年大促</a></h4>

<p>苹果于 1 月 3 日放出一则清新醒神的优惠大消息：苹果红色星期五正式回归，优惠力度可能是多年来最强的一次。</p>

<h2>开发</h2>

<h4>1) <a href="https://gold.xitu.io/post/586629b861ff4b006ba9daf6">微信 Mars 之 xlog 使用全解析</a> By 徐宜生</h4>

<p>微信开源的通信库 Mars，其中有一个高性能的日志模块 xlog。本篇文章将带领大家将 xlog 模块抽取出来，作为一个单独的模块来使用。</p>

<h4>2) <a href="https://lunapps.com/blog/onboarding-framework-for-ios/">How we built LUNTutorialViewController</a> By LUNAPPS</h4>

<p>LUNTutorialViewController 这个引导页效果在很多 APP 里都能看到身影，本文详细介绍了其设计与实现。</p>

<h2>工具</h2>

<h4>1) <a href="http://videodownloader.ummy.net/mac.html">Ummy Video Downloader</a> By Ummy</h4>

<p>正如官网介绍的那样，The simplest YouTube downloader for Mac，诚不欺也。看到 Youtube 上好看的节目，我还是喜欢下载下来到电视上播放。</p>

<h4>2) <a href="https://chrome.google.com/webstore/detail/tumblr%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD/njnkdhldbefijmdmjongfghcelgajjli">Tumblr video downloader</a> By unclehking</h4>

<p>这是一个 Chrome 插件，方便下载 Tumblr 上的视频用的。</p>

<h2>其他</h2>

<h4>1) <a href="http://www.geeksforgeeks.org/top-10-algorithms-in-interview-questions/">Top 10 algorithms in Interview Questions</a> By GeeksforGeeks</h4>

<p>针对八类问题分别给出了最常见的十道算法题及其解答，适合年后准备面试的同学。</p>

<p>@end</p>
]]></content>
  </entry>
  
</feed>
