/
index.html
478 lines (337 loc) · 26.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>iOS应用内付费(IAP)开发步骤列表 | 唐巧的博客</title>
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<meta name="author" content="唐巧">
<meta name="description" content="前两天和服务端同事一起,完成了应用内付费(以下简称IAP, In app purchase)的开发工作。步骤繁多,在此把开发步骤列表整理如下。因为只是步骤列表,所以并不含详细的说明教程,需要看教程的新手,可以看我附在最后的一些参考链接。">
<meta property="og:type" content="article">
<meta property="og:title" content="iOS应用内付费(IAP)开发步骤列表">
<meta property="og:url" content="https://blog.devtang.com/2012/12/09/in-app-purchase-check-list/index.html">
<meta property="og:site_name" content="唐巧的博客">
<meta property="og:description" content="前两天和服务端同事一起,完成了应用内付费(以下简称IAP, In app purchase)的开发工作。步骤繁多,在此把开发步骤列表整理如下。因为只是步骤列表,所以并不含详细的说明教程,需要看教程的新手,可以看我附在最后的一些参考链接。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://blog.devtang.com/images/iap-add-product-id.png">
<meta property="og:image" content="https://blog.devtang.com/images/iap-adduser-1.png">
<meta property="og:image" content="https://blog.devtang.com/images/iap-adduser-2.png">
<meta property="og:image" content="https://blog.devtang.com/images/iap-tax-info.png">
<meta property="article:published_time" content="2012-12-09T04:55:00.000Z">
<meta property="article:modified_time" content="2020-02-08T18:08:22.157Z">
<meta property="article:author" content="唐巧">
<meta property="article:tag" content="iOS">
<meta property="article:tag" content="唐巧">
<meta property="article:tag" content="猿辅导">
<meta property="article:tag" content="开发">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://blog.devtang.com/images/iap-add-product-id.png">
<link rel="alternative" href="/atom.xml" title="唐巧的博客" type="application/atom+xml">
<link rel="icon" href="/img/favicon.png">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/%02.css">
<link rel="stylesheet" href="/.css">
<meta name="generator" content="Hexo 4.2.0"></head>
<body>
<header>
<div>
<div id="textlogo">
<h1 class="site-name"><a href="/" title="唐巧的博客">唐巧的博客</a></h1>
<h2 class="blog-motto">记录下自己学习的点滴</h2>
</div>
<div class="navbar"><a class="navbutton navmobile" href="#" title="菜单">
</a></div>
<nav class="animated">
<ul>
<ul>
<li><a href="/">首页</a></li>
<li><a href="/archives">归档</a></li>
<li><a href="/about">关于</a></li>
<li>
<form class="search" action="//google.com/search" method="get" accept-charset="utf-8">
<label>Search</label>
<input type="search" id="search" name="q" autocomplete="off" maxlength="20" placeholder="搜索" />
<input type="hidden" name="q" value="site:blog.devtang.com">
</form>
</li>
</ul>
</nav>
</div>
</header>
<div id="container">
<div id="main" class="post" itemscope itemprop="blogPost">
<article itemprop="articleBody">
<header class="article-info clearfix">
<h1 itemprop="name">
<a href="/2012/12/09/in-app-purchase-check-list/" title="iOS应用内付费(IAP)开发步骤列表" itemprop="url">iOS应用内付费(IAP)开发步骤列表</a>
</h1>
<p class="article-time">
<time datetime="2012-12-09T04:55:00.000Z" itemprop="datePublished"> 发表于 2012-12-09 04:55</time>
</p>
</header>
<div class="article-content">
<div id="toc" class="toc-article">
<strong class="toc-title">文章目录</strong>
<ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#配置Developer-apple-com"><span class="toc-number">1.</span> <span class="toc-text">配置Developer.apple.com</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#配置iTunes-Connect"><span class="toc-number">2.</span> <span class="toc-text">配置iTunes Connect</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#参考链接"><span class="toc-number"></span> <span class="toc-text">参考链接</span></a>
</div>
<p>前两天和服务端同事一起,完成了应用内付费(以下简称IAP, In app purchase)的开发工作。步骤繁多,在此把开发步骤列表整理如下。因为只是步骤列表,所以并不含详细的说明教程,需要看教程的新手,可以看我附在最后的一些参考链接。</p>
<a id="more"></a>
<h3 id="配置Developer-apple-com"><a href="#配置Developer-apple-com" class="headerlink" title="配置Developer.apple.com"></a>配置Developer.apple.com</h3><p>登录到<a href="https://developer.apple.com/" target="_blank" rel="noopener">Developer.apple.com</a>,然后进行以下步骤:</p>
<ol>
<li>为应用建立建立一个不带通配符的App ID</li>
<li>用该App ID生成和安装相应的Provisioning Profile文件。</li>
</ol>
<h3 id="配置iTunes-Connect"><a href="#配置iTunes-Connect" class="headerlink" title="配置iTunes Connect"></a>配置iTunes Connect</h3><p>登录到<a href="https://itunesconnect.apple.com/" target="_blank" rel="noopener">iTunes Connet</a>,然后进行以下步骤:</p>
<ol>
<li>用该App ID创建一个新的应用。</li>
<li>在该应用中,创建应用内付费项目,选择付费类型,通常可选的是可重复消费(Consumable)的或是永久有效(Non-Consumable)的2种,然后设置好价格和Product ID以及购买介绍和截图即可,这里的Product ID是需要记住的,后面开发的时候需要。如下图所示:<img src="/images/iap-add-product-id.png" class="">
</li>
</ol>
<ol start="3">
<li><p>添加一个用于在sandbox付费的测试用户,如下图所示。注意苹果对该测试用户的密码要求<br>和正式账号一样,必须是至少8位,并且同时包含数字和大小写字母:</p>
<img src="/images/iap-adduser-1.png" class="">
<img src="/images/iap-adduser-2.png" class="">
</li>
<li><p>填写相关的税务,银行,联系人信息。如下图所示:</p>
<img src="/images/iap-tax-info.png" class="">
</li>
</ol>
<p>###开发工作(ios端)</p>
<p>1、 在工程中引入 storekit.framework 和 #import <StoreKit/StoreKit.h></p>
<p>2、 获得所有的付费Product ID列表。这个可以用常量存储在本地,也可以由自己的服务器返回。</p>
<p>3、 制作一个界面,展示所有的应用内付费项目。这些应用内付费项目的价格和介绍信息可以是自己的服务器返回。但如果是不带服务器的单机游戏应用或工具类应用,则可以通过向App Store查询获得。我在测试时发现,向App Store查询速度非常慢,通常需要2-3秒钟,所以不建议这么做,最好还是搞个自己的服务器吧。</p>
<p>4、当用户点击了一个IAP项目,我们先查询用户是否允许应用内付费,如果不允许则不用进行以下步骤了。代码如下:</p>
<figure class="highlight objc"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> ([<span class="built_in">SKPaymentQueue</span> canMakePayments]) {</span><br><span class="line"> <span class="comment">// 执行下面提到的第5步:</span></span><br><span class="line"> [<span class="keyword">self</span> getProductInfo];</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">NSLog</span>(<span class="string">@"失败,用户禁止应用内付费购买."</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>5、 我们先通过该IAP的ProductID向AppStore查询,获得SKPayment实例,然后通过SKPaymentQueue的 addPayment方法发起一个购买的操作。</p>
<figure class="highlight objc"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 下面的ProductId应该是事先在itunesConnect中添加好的,已存在的付费项目。否则查询会失败。</span></span><br><span class="line">- (<span class="keyword">void</span>)getProductInfo {</span><br><span class="line"> <span class="built_in">NSSet</span> * set = [<span class="built_in">NSSet</span> setWithArray:@[<span class="string">@"ProductId"</span>]];</span><br><span class="line"> <span class="built_in">SKProductsRequest</span> * request = [[<span class="built_in">SKProductsRequest</span> alloc] initWithProductIdentifiers:set];</span><br><span class="line"> request.delegate = <span class="keyword">self</span>;</span><br><span class="line"> [request start];</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">void</span>)productsRequest:(<span class="built_in">SKProductsRequest</span> *)request didReceiveResponse:(<span class="built_in">SKProductsResponse</span> *)response {</span><br><span class="line"> <span class="built_in">NSArray</span> *myProduct = response.products;</span><br><span class="line"> <span class="keyword">if</span> (myProduct.count == <span class="number">0</span>) {</span><br><span class="line"> <span class="built_in">NSLog</span>(<span class="string">@"无法获取产品信息,购买失败。"</span>);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">SKPayment</span> * payment = [<span class="built_in">SKPayment</span> paymentWithProduct:myProduct[<span class="number">0</span>]];</span><br><span class="line"> [[<span class="built_in">SKPaymentQueue</span> defaultQueue] addPayment:payment];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>6、 在viewDidLoad方法中,将购买页面设置成购买的Observer。</p>
<figure class="highlight objc"><table><tr><td class="code"><pre><span class="line">- (<span class="keyword">void</span>)viewDidLoad {</span><br><span class="line"> [<span class="keyword">super</span> viewDidLoad];</span><br><span class="line"> <span class="comment">// 监听购买结果</span></span><br><span class="line"> [[<span class="built_in">SKPaymentQueue</span> defaultQueue] addTransactionObserver:<span class="keyword">self</span>];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (<span class="keyword">void</span>)viewDidUnload {</span><br><span class="line"> [<span class="keyword">super</span> viewDidUnload];</span><br><span class="line"> [[<span class="built_in">SKPaymentQueue</span> defaultQueue] removeTransactionObserver:<span class="keyword">self</span>];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>7、 当用户购买的操作有结果时,就会触发下面的回调函数,相应进行处理即可。</p>
<figure class="highlight objc"><table><tr><td class="code"><pre><span class="line">- (<span class="keyword">void</span>)paymentQueue:(<span class="built_in">SKPaymentQueue</span> *)queue updatedTransactions:(<span class="built_in">NSArray</span> *)transactions {</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">SKPaymentTransaction</span> *transaction <span class="keyword">in</span> transactions)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">switch</span> (transaction.transactionState)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> <span class="built_in">SKPaymentTransactionStatePurchased</span>:<span class="comment">//交易完成</span></span><br><span class="line"> <span class="built_in">NSLog</span>(<span class="string">@"transactionIdentifier = %@"</span>, transaction.transactionIdentifier);</span><br><span class="line"> [<span class="keyword">self</span> completeTransaction:transaction];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="built_in">SKPaymentTransactionStateFailed</span>:<span class="comment">//交易失败</span></span><br><span class="line"> [<span class="keyword">self</span> failedTransaction:transaction];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="built_in">SKPaymentTransactionStateRestored</span>:<span class="comment">//已经购买过该商品</span></span><br><span class="line"> [<span class="keyword">self</span> restoreTransaction:transaction];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="built_in">SKPaymentTransactionStatePurchasing</span>: <span class="comment">//商品添加进列表</span></span><br><span class="line"> <span class="built_in">NSLog</span>(<span class="string">@"商品添加进列表"</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="keyword">break</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><br><span class="line">- (<span class="keyword">void</span>)completeTransaction:(<span class="built_in">SKPaymentTransaction</span> *)transaction {</span><br><span class="line"> <span class="comment">// Your application should implement these two methods.</span></span><br><span class="line"> <span class="built_in">NSString</span> * productIdentifier = transaction.payment.productIdentifier;</span><br><span class="line"> <span class="built_in">NSString</span> * receipt = [transaction.transactionReceipt base64EncodedString];</span><br><span class="line"> <span class="keyword">if</span> ([productIdentifier length] > <span class="number">0</span>) {</span><br><span class="line"> <span class="comment">// 向自己的服务器验证购买凭证</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Remove the transaction from the payment queue.</span></span><br><span class="line"> [[<span class="built_in">SKPaymentQueue</span> defaultQueue] finishTransaction: transaction];</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (<span class="keyword">void</span>)failedTransaction:(<span class="built_in">SKPaymentTransaction</span> *)transaction {</span><br><span class="line"> <span class="keyword">if</span>(transaction.error.code != <span class="built_in">SKErrorPaymentCancelled</span>) {</span><br><span class="line"> <span class="built_in">NSLog</span>(<span class="string">@"购买失败"</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">NSLog</span>(<span class="string">@"用户取消交易"</span>);</span><br><span class="line"> }</span><br><span class="line"> [[<span class="built_in">SKPaymentQueue</span> defaultQueue] finishTransaction: transaction];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (<span class="keyword">void</span>)restoreTransaction:(<span class="built_in">SKPaymentTransaction</span> *)transaction {</span><br><span class="line"> <span class="comment">// 对于已购商品,处理恢复购买的逻辑</span></span><br><span class="line"> [[<span class="built_in">SKPaymentQueue</span> defaultQueue] finishTransaction: transaction];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>8、服务器验证凭证(Optional)。如果购买成功,我们需要将凭证发送到服务器上进行验证。考虑到网络异常情况,iOS端的发送凭证操作应该进行持久化,如果程序退出,崩溃或网络异常,可以恢复重试。</p>
<p>###开发工作(服务端)</p>
<p>服务端的工作比较简单,分4步:</p>
<ol>
<li>接收ios端发过来的购买凭证。</li>
<li>判断凭证是否已经存在或验证过,然后存储该凭证。</li>
<li>将该凭证发送到苹果的服务器验证,并将验证结果返回给客户端。</li>
<li>如果需要,修改用户相应的会员权限。</li>
</ol>
<p>考虑到网络异常情况,服务器的验证应该是一个可恢复的队列,如果网络失败了,应该进行重试。</p>
<p>与苹果的验证接口文档在<a href="https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html#//apple_ref/doc/uid/TP40008267-CH104-SW3" target="_blank" rel="noopener">这里</a>。简单来说就是将该购买凭证用Base64编码,然后POST给苹果的验证服务器,苹果将验证结果以JSON形式返回。</p>
<p>苹果AppStore线上的购买凭证验证地址是<a href="https://buy.itunes.apple.com/verifyReceipt" target="_blank" rel="noopener">https://buy.itunes.apple.com/verifyReceipt</a> ,测试的验证地址是:<a href="https://sandbox.itunes.apple.com/verifyReceipt" target="_blank" rel="noopener">https://sandbox.itunes.apple.com/verifyReceipt</a></p>
<h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><p>以下参考链接详细说明了完成应用内付费开发的步骤:</p>
<ol>
<li><a href="https://developer.apple.com/appstore/in-app-purchase/index.html" target="_blank" rel="noopener">https://developer.apple.com/appstore/in-app-purchase/index.html</a></li>
<li><a href="http://www.himigame.com/iphone-cocos2d/550.html" target="_blank" rel="noopener">http://www.himigame.com/iphone-cocos2d/550.html</a></li>
<li><a href="http://www.cocoachina.com/iphonedev/sdk/2011/1028/3435.html" target="_blank" rel="noopener">http://www.cocoachina.com/iphonedev/sdk/2011/1028/3435.html</a></li>
<li><a href="http://www.cocoachina.com/newbie/basic/2012/0214/3976.html" target="_blank" rel="noopener">http://www.cocoachina.com/newbie/basic/2012/0214/3976.html</a></li>
</ol>
</div>
<footer class="article-footer clearfix">
<div class="article-catetags">
<div class="article-categories">
<span></span>
<a class="article-category-link" href="/categories/iOS/">iOS</a>
</div>
</div>
<div class="article-share" id="share">
<div data-url="https://blog.devtang.com/2012/12/09/in-app-purchase-check-list/" data-title="iOS应用内付费(IAP)开发步骤列表 | 唐巧的博客" data-tsina="" class="share clearfix">
</div>
</div>
</footer>
</article>
<nav class="article-nav clearfix">
<div class="prev" >
<a href="/2012/12/09/iap-crack-issue/" title="关于IAP的破解">
<strong>上一篇:</strong><br/>
<span>
关于IAP的破解</span>
</a>
</div>
<div class="next">
<a href="/2012/12/08/use-privoxy/" title="使用Privoxy做智能代理切换">
<strong>下一篇:</strong><br/>
<span>使用Privoxy做智能代理切换
</span>
</a>
</div>
</nav>
</div>
<div class="openaside"><a class="navbutton" href="#" title="显示侧边栏"></a></div>
<div id="asidepart">
<div class="closeaside"><a class="closebutton" href="#" title="隐藏侧边栏"></a></div>
<aside class="clearfix">
<div class="sponsor">
</div>
<div class="categorieslist">
<p class="asidetitle">分类</p>
<ul>
<li><a href="/categories/books-summary/" title="books summary">books summary</a></li>
<li><a href="/categories/iOS/" title="iOS">iOS</a></li>
<li><a href="/categories/iOS-weekly/" title="iOS weekly">iOS weekly</a></li>
<li><a href="/categories/mac/" title="mac">mac</a></li>
<li><a href="/categories/shell/" title="shell">shell</a></li>
<li><a href="/categories/summary/" title="summary">summary</a></li>
</ul>
</div>
<div class="weixin">
<br />
<p class="asidetitle">微信公众号</p>
<p>关注我的微信公众号,和我一起成长:</p>
<img src="/images/weixin-qr.jpg" width="230px" />
</div>
<div class="rsspart">
<a href="/atom.xml" target="_blank" title="rss">RSS 订阅</a>
</div>
</aside>
</div>
</div>
<footer><div id="footer" >
<div class="social-font" class="clearfix">
</div>
<p class="copyright" style="margin-top: 10px;">
Powered by <a href="http://hexo.io" target="_blank" title="hexo">hexo</a> and Theme by <a href="https://github.com/wuchong/jacman" target="_blank" title="Jacman">Jacman</a> © 2020
<a href="/about" target="_blank" title="唐巧">唐巧</a>
</p>
</div>
</footer>
<script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/jquery.imagesloaded.min.js"></script>
<script src="/js/gallery.js"></script>
<script src="/js/jquery.qrcode-0.12.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.navbar').click(function(){
$('header nav').toggleClass('shownav');
});
var myWidth = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
};
var m = $('#main'),
a = $('#asidepart'),
c = $('.closeaside'),
o = $('.openaside');
c.click(function(){
a.addClass('fadeOut').css('display', 'none');
o.css('display', 'block').addClass('fadeIn');
m.addClass('moveMain');
});
o.click(function(){
o.css('display', 'none').removeClass('beforeFadeIn');
a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');
m.removeClass('moveMain');
});
$(window).scroll(function(){
o.css("top",Math.max(80,260-$(this).scrollTop()));
});
$(window).resize(function(){
getSize();
if (myWidth >= 1024) {
$('header nav').removeClass('shownav');
}else{
m.removeClass('moveMain');
a.css('display', 'block').removeClass('fadeOut');
o.css('display', 'none');
}
});
});
</script>
<script type="text/javascript">
$(document).ready(function(){
var ai = $('.article-content>iframe'),
ae = $('.article-content>embed'),
t = $('#toc'),
ta = $('#toc.toc-aside'),
o = $('.openaside'),
c = $('.closeaside');
if(ai.length>0){
ai.wrap('<div class="video-container" />');
};
if(ae.length>0){
ae.wrap('<div class="video-container" />');
};
c.click(function(){
ta.css('display', 'block').addClass('fadeIn');
});
o.click(function(){
ta.css('display', 'none');
});
$(window).scroll(function(){
ta.css("top",Math.max(140,320-$(this).scrollTop()));
});
});
</script>
<script type="text/javascript">
$(document).ready(function(){
var $this = $('.share'),
url = $this.attr('data-url'),
encodedUrl = encodeURIComponent(url),
title = $this.attr('data-title'),
tsina = $this.attr('data-tsina'),
description = $this.attr('description');
var html = [
'<div class="hoverqrcode clearfix"></div>',
'<a class="overlay" id="qrcode"></a>',
'<a href="https://www.facebook.com/sharer.php?u=' + encodedUrl + '" class="article-share-facebook" target="_blank" title="Facebook"></a>',
'<a href="https://twitter.com/intent/tweet?url=' + encodedUrl + '" class="article-share-twitter" target="_blank" title="Twitter"></a>',
'<a href="#qrcode" class="article-share-qrcode" title="微信"></a>',
'<a href="http://widget.renren.com/dialog/share?resourceUrl=' + encodedUrl + '&srcUrl=' + encodedUrl + '&title=' + title +'" class="article-share-renren" target="_blank" title="人人"></a>',
'<a href="http://service.weibo.com/share/share.php?title='+title+'&url='+encodedUrl +'&ralateUid='+ tsina +'&searchPic=true&style=number' +'" class="article-share-weibo" target="_blank" title="微博"></a>',
'<span title="Share to"></span>'
].join('');
$this.append(html);
$('.hoverqrcode').hide();
var myWidth = 0;
function updatehoverqrcode(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
var qrsize = myWidth > 1024 ? 200:100;
var options = {render: 'image', size: qrsize, fill: '#2ca6cb', text: url, radius: 0.5, quiet: 1};
var p = $('.article-share-qrcode').position();
$('.hoverqrcode').empty().css('width', qrsize).css('height', qrsize)
.css('left', p.left-qrsize/2+20).css('top', p.top-qrsize-10)
.qrcode(options);
};
$(window).resize(function(){
$('.hoverqrcode').hide();
});
$('.article-share-qrcode').click(function(){
updatehoverqrcode();
$('.hoverqrcode').toggle();
});
$('.article-share-qrcode').hover(function(){}, function(){
$('.hoverqrcode').hide();
});
});
</script>
<!-- Analytics Begin -->
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-28029597-1', '');
ga('send', 'pageview');
</script>
<!-- Analytics End -->
<!-- Totop Begin -->
<div id="totop">
<a title="返回顶部"><img src="/img/scrollup.png"/></a>
</div>
<script src="/js/totop.js"></script>
<!-- Totop End -->
<!-- MathJax Begin -->
<!-- mathjax config similar to math.stackexchange -->
<!-- MathJax End -->
<!-- Tiny_search Begin -->
<!-- Tiny_search End -->
</body>
</html>