• iPhone上通过http传递JSON数据




    本教程介绍了在iPhone程序中怎样访问JSON web service的详细步骤。


    读文章 »

     
  • IAP(程序内购买): 完全攻略

    第一印象觉得In-App Purchase(简称IAP)非常简单。Apple提供的大量文档应该让开发者很快熟悉地熟悉。那么,为什么在你的应用中集成IAP特性就如此令人生厌呢?


    这是因为在开发过程中不可避免会出现一些错误。而但这些错误发生的时候,你就抓瞎了。虽然Apple提供了有关IAP的大量文档,但他们并未提及集成IAP的详细步骤。而且对StoreKit集成过程中出现的问题也没有一个核对清单。另外对于为什么诸如产品ID非法之类的问题也没有提供NSError之类的对象来告诉你原因。


    在试用了各种可能的解决方案后,你只能身心疲惫,彷徨无助。


    为了提高你的效率和减少你的痛苦,我觉定利用此文来介绍一下实现IAP的详细步骤。本文很详细,有点长。甚至可能太长了,但不像Apple的文档,它提供了为实现IAP的每一个步骤。


    废话少说,我们直入主题吧。


    读文章 »

     
  • 以密码方式显示UITextField文本

    很简单,如下:

    1
    textField.secureTextEntry = YES;


     
  • iPhone用Expat XML解析器

    xml的解析运用的十分广泛,我以前也介绍过使用ticpp(tinyxml的c++版本)进行简单的xml解析,见跨平台代码分享之三–xml解析器,它是采用DOM进行解析。iPhone SDK中自带的NSXMLParsers也可进行xml解析,但是对于解析web server下载的大型文件时效率不够高,有一个第三方的objective c expat wrapper 采用expat(SAX方式)进行解析,效率非常高。据有人测试,其效率相对于NSXMLParsers约提高了70-80%。


    下面是其下载地址



     
  • 调试教程 – 使用UIRecorder Instrument将测试自动化

    (注:这是我以前收集的一篇文章,找不到出处了,稍作修改在此发布)


    如果你发现程序的bug,但每次进行测试都需要许多步骤才能重现问题,那么本教程适合你。通常,测试和调试是非常繁琐的事情,iPhone程序的开发尤其如此。

    读文章 »

     
  • OpenAL同时处理大量声音

    (注:这是我在编写MozartBrain时,参考过的一篇文章,虽然年代久远,但对于学习OpenAL编程还是具有指导意义。)


    今天要讨论的话题是OpenAL同时处理大量的音效。当你使用OpenAL进行声音播放时,能够同时播放的声音有一个上限(换而言之,最大的source数目)。在iPhone上能够通过下面代码获得的最大source数目大约为32:


    1
    alGenSources(1, &sourceID);


    当你要求超过最大数目的source时,上面的语句将失败,但它并不产生错误。因此,不要要求超过32个source(注:这是iPhone OS 2.2上的数目,其他版本的OS可能会有些差别)


    所以,这意味着什么?它意味着任何时候不管什么原因都不要同时播放超过32个音效。这确实是一个问题,如果你的目标是通过分别播放各种乐器来模拟整个交响乐团的演奏,那么你最好不要在iPhone上尝试这样做。

    我以前的文章中提到建议为每个音效(音效缓存)分配一个source并在需要播放时都调用此source。这在大部分情形下都可以正常工作。但是,如果在你的应用程序中有超过32个音效时,你应该怎么做?我记得曾经提到过:你应该将未用的source移交给将要被播放的buffer。


    读文章 »

     
  • 创建离线iPhone Web App

    创建Web App的好处很多,比如:


    • 可以运行在任何平台上 (当然要考虑浏览器的兼容性和屏幕大小问题)
    • 不需要学习iPhone编程语言
    • 最大的好处是不需要经过App Store批准


    随着Internet技术的迅速发展,使得Web App越来越强大,从简单的应用甚至到游戏,都可能通过Web App实现。但是,它要求随时连接到Internet,大大降低了Web App的实用性。随着Safari对HTML 5的支持,使得Web App的离线运行成为可能。这意味着你可以在没有Internet连接的情况下运行你的应用程序。


    下面的例子改编自How to Make an HTML5 iPhone App,它介绍了创建一个离线“积木”游戏的全过程,我加上了创建用户自定义的桌面图标和启动画面的方法,使它看上去完全像一个真正的iPhone应用程序,而这是完全不需要通过Apple的App Store批准的。

    读文章 »

     
  • iPad 编程教程 – Hello World++

    概述


    随着iPad的发布,我想很多人开始绞尽脑汁试图在新一轮的“淘金热”中抢占一块市场。iCodeBlog将推出一系列iPad教程帮助大家。


    由于iPad使用iPhone同样的SDK,所有代码看上去完全一样。实际上,看看最新和修改了的API类,你就会发现大部分是有关用户界面的。这是一个好消息,因为我们都对iPhone编程有了一定的经验。


    此教程被称为“Hello World”,实际上它远远不止这些。首先,我假定你们已经具有iPhone/Objective-C的编程经验。


    读文章 »

     
  • 从零开始学习OpenGL ES之七 – 变换和矩阵

    今天的主题是我一度谈之色变的。概念上讲,它是3D编程中最为困难的部分。


    首先,你应该理解 3D 几何和笛卡尔坐标系他。你还应该理解由顶点构成的三角形组成的OpenGL虚拟世界的物体,各顶点定义了三维空间的特定点,你还应理解怎样使用这些信息在 iPhone上使用OpenGL ES进行绘制。如果你不理解这些概念,我建议你回头再看看我的前六篇文章。


    为在交互式程序如游戏中使用这些虚拟世界中的物体,必须要有一种方法来改变物体间的相对位置以及物体与观察者之间的相对位置。要有一种方法不但可以移动,而且可以旋转和改变物体的大小。

    还必须要有一种方法将虚拟的三维坐标转换成电脑屏幕的二维坐标。所有这些都是通过所谓变换来实现的。实现变换的内部机制是就是矩阵


    尽管你不需要懂得太多有关矩阵和矩阵的数学知识就可以实现许多OpenGL的功能,但对这些观念的基本理解有很大的帮助。

    读文章 »

     
  • OpenGL ES纹理尺寸限制的处理方法

    大家都知道,OpenGL ES对纹理的尺寸有限制,就是长和宽都必须是2的整数次幂。(实际上OpenGL都有此限制,但有一些扩展可以解决此问题)。因此处理方案有两种:


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


    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
            // 首先调整纹理的长和宽为2的整数次幂        
            if( (_width != 1) && (_width & (_width - 1)) )
            {
                    i = 1;
                    while((sizeToFit ? 2 * i : i) < _width)
                            i *= 2;
                    _width = i;
            }

            if( (_height != 1) && (_height & (_height - 1)) )
            {
                    i = 1;
                    while((sizeToFit ? 2 * i : i) < _height)
                            i *= 2;
                    _height = i;
            }

            // 如果调整后的图像尺寸大于最大纹理尺寸(1024),那么需要缩小
            while((_width &gt; kMaxTextureSize) || (_height &gt; kMaxTextureSize))
            {
                _width /= 2;
                _height /= 2;
                transform = CGAffineTransformScale(transform, 0.5, 0.5);
                imageSize.x *= 0.5;
                imageSize.y *= 0.5;
            }