Ionic

安装node.js npm
http://nodejs.cn/download/releases/
https://nodejs.org/download/release/v5.1.1/node-v5.1.1.pkg

安装cordova
# npm install -g cordova
安装完毕
# cordova –version
5.2.0

安装ionic
# npm install -g ionic -d
# ionic –version
1.6.4

运行程序
ionic serve
1

GCDAsyncSocket类库,IOS下TCP通讯使用心得

关于在IOS下使用Socket进行通讯的技术文章也许诺很久了,今日又是一个还债的日子,网上虽然很多介绍过AsyncSocket或GCDAsyncSocket的文章,但其实就那么一两篇大部分都是转载,于是我义正言辞、慷慨激昂的批判他们这种不负责任的态度,学习,不是给自己学的,是要和大家分享的。技术的共享有利于整体行业的进步,也可以使自身更深入全面的了解。

之前的文章中我们讲到过TCP通讯协议,并且也对其进行了较为详细的介绍和描述,关于TCP通讯的原理此处我们不再赘述,如有需要的看官可自行翻阅本人所写的《IOS、安卓IM语音聊天开发初探部分心得——网络基础篇》一文。

正如名称一样GCDAsyncSocket开源类库是以苹果的GCD多任务处理机制完成的一个异步交互套接字通讯。使用方法其实并不复杂,主要说的是在使用这个类库的时候我的一些心得和理解,若有不妥之处望看官指点。首先,每一个GCDAsyncSocket对象(以下简称GCDSocket对象)都可以理解为一个socket套接字,我们的操作都是针对于这个socket执行的各种命令,可以打开一个端口侦听,同样也可以连接其他计算机的端口进行数据通讯等等等等。首先我们来创建一个socket。当然这之前先要将CGDAsyncSocket的.h文件及.m文件加入到我们的项目,并且在需要使用socket连接的地方将.h头文件包含,这些废话我觉得不需要复述了应该(那你还嘚吧嘚的说半天干嘛啊喂!)。具体代码如下

GCDAsyncSocket  socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

代码并不复杂,我们只需要给出一个委托对象也就是第一个参数中的self,以及一个委托运行的GCD队列即可创建一个GCDAsyncSocket,当前代码中我们是使用静态全局函数取得的主消息队列。当然也可以使用其他方法获得其他的GCD队列,比如:dispatch_get_global_queue().

创建了Socket对象我们即可以立即为,当前我们的socket已经进入程序以供操作。但如果你想和服务器进行通讯,那么我们还需要和服务器进行连接。可能有的使用习惯了http协议的人会问,初始化函数中我们为何不直接指定服务器以及端口号?其实这些肯定都是需要的,但是你要理解到,你的socket对象功能不只是可以用来连接服务器,换而言之我们的socket对象一样可以侦听某端口来等待他人连接,所以在通过套接字编程使用TCP协议的时候是我们从http协议过度到TCP协议的一个转变(虽然本文并不会教你如何在IOS上构架服务器。),但并不是第一个,第一个转变是要记得,我们要使用的是协议,并非某个类,所以我上述说明中都是说从http协议过度到TCP而不是跟大家说现在我们将从NSURLRequest和NSURLConnection过度到GCDAsyncSocket。

好了接下来我们看看如何连接服务器。源代码如下:

NSError *err;

[socket connectToHost:@“192.168.10.111” onPort@”60000″ error:&err];

if (err != nil)

{

NSLog(@”%@”,err);

}

代码比前面稍微长了一点,不过实质上完全不复杂,我们只是先声明了一个错误信息的指针,然后使用之前创建的对象调用他的连接方法,第一个参数不难看出是一个IP,第二个参数则是一个端口,如果这里还不理解何为IP和端口的话,就先去看看在开头就提到的我之前写过的那边网络基础篇文章吧…最后一个是出参,如果连接的过程中出现了错误,该方法会把这根指针指向一个具体的错误信息,最后我们再判断一下之前我们创建错误信息的指针是否还是指向空,如果并非指向空那么代表我们连接的过程中出现了错误,将错误信息打印一下吧~不过请切记,此处的错误信息并非你创建连接时所有的错误都会在此处得到反映。

说到这里我们该说一点真正有用的了,GCDAsyncSocket具有一系列完整的委托机制,我们所做的一切处理基本都是异步处理的状态,换句话说,连接之后是否连接成功,连接成功要执行什么懂并非应该写在此处而应该写在相应的委托之中,同样的道理一样适用于发送、读取数据等等。也就是说我们在此处读出的错误只是同步执行的代码处理一些连接时会发生的错误,而更多的处理我们应在相对应的委托中进行处理。首先请看下面这个方法:

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port

这个方法就是在成功连接服务器之后的委托方法。关于委托该如何使用我在此处就不赘述了和本文的关系实在不大,不过给诸位看管一个建议,也是我才刚刚纠正的一个编码错误习惯,之前碰到所有委托的地方我都会将直接将当前的类对象设置成委托处理对象,并且遵循委托协议扩充代码,这么做的坏处显而易见,显示层与逻辑层的混淆是一方面,另一方面是一旦需要使用过多的委托,将造成大量不必要的代码都堆积在一个类中,并且我们很容易直接在委托方法中直接使用一些类内成员属性或者甚至是私有成员,而实际上这种做法是很不好的,因为这种最发会使得逻辑出现混乱,处理委托应当是单独处于后台的逻辑,如果需要一些必要的数据传递也应该采取属性侦听、甚至是通知等方式来实现而并非直接在显示层中编写逻辑代码来实现。使得代码耦合性大增的同时也使得很多时候在切换操作对象时对委托对象的处理变得复杂,甚至可能完全相同的代码要难免的复制粘贴。所以我给大家的建议是单独编写一个委托类,在每个类中设置一个该类类型的成员指针,将委托设置到专门的委托对象上去处理,这样不仅效率更高,代码可读性更强,更便于维护,同时也更符合面向对象的编程思想。

回到对GCDAsyncSocket使用的讲解上来,在这个委托方法中,我们可以取到一个socket对象一个服务器IP和一个端口号,你可以处理一切在连接建立之后应该马上执行的事情,比如与服务器进行通信确认连接端以免出现其他人通过IP及端口随意的和你的服务器通信,再比如开启心跳包的发送,让服务器一直可以确认你的存在。不管做什么,都是你和服务器的编写者事前约定好的,就像数据传输格式什么的,如果没有当面约定我坚信他也一定要给你出个文档什么的,否则你的工作接下来将举步维艰。但是不管你要在此处都做什么工作,都要处理哪些事宜,请务必记得,在此处你必须要在函数的最后加上一句:

[socket readDataWithTimeout:-1 tag:0];

这是什么?别慌,按照你看到这个函数的第一反应取理解,没错他就是读取数据的方法,两个参数也略显简单,一个超时时间,如果你设置成-1则认为永不超时,而第二参数则是区别该次读取与其他读取的标志,通常我们在设计视图上的控件时也会有这样的一个属性就是tag。如果你做过web开发,那你应该知道Http标签上的id,如果你做过一些桌面级开发,你的控件或许有个id或者是index再或者是tag的属性来区别这些控件,没错此tag和彼tag功效基本一样。

我们可以这样理解,socket在开启之前是一个巨大门,开启这道门之后(也就是连接之后)就是一个宽敞的通道,通过这条通道所达到的地点就是我们连接的目标服务器,或者是连接过来的客户端,两面都是一样的。我们现在不论是发送数据还是读取数据都是往返于这个大门之中的一个个门卫与邮递员,我们可以把读取数据的方法看作是门卫,而发送数据的人看做是邮递员,没错服务器与客户端都一样,我们都会派出一个个邮递员去我们连接的另一端送信,但是如果你没有命令你的门卫去吧门口邮箱中的信拿过来,那么你的邮递员就会假装看不见邮递员,然后呼呼睡大觉,好吧看起来这些门卫实在没什么责任心不是么,其实他们也是有苦衷的,因为这是最初设计者给他们的命令,不接到命令绝对不要出门,万一收到的是金刚葫芦娃高清全集的种子怎么办!好的就这样,为了避免我们的邮件不被错过,所以建立连接之后就让一个门卫跑去门口等着吧~慢着,万一我需要派出很多个门卫我分不清他们该怎么办,其实他们已经被你分配了工号,这个工号就是tag。

现在我们的连接动作算是完整的做完了,接下来我们要做的就只有两件事,第一个在需要发送数据的时候派出邮递员,以及当门卫接到消息的时候在我们的手机端上根据门卫的消息做出反应。等等,好像少了点什么,没错 少点委托,我们来看一下读取和写入的委托,读取的委托即是门卫接到信息的报告,写入的委托就是邮递员将邮件送完的回复:

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag

好的让我们来看看这些委托中我们都能得到什么,首先是读取的委托,是一个socket对象,一个读取到的数据以及一个“门卫的工号”,嗯,大概也就这些,我们还能要什么的,没错这些足够了,别抱怨第二个参数的数据类型,要知道其实最开始接到数据的时候只是字节数组啊,已经给你转换成NSData对象了你就要学会感恩啊,谁让你要用套接字传输了,这就是活该的,所以改怎么读取转换解析这些数据你需要好好的和服务器编写者沟通。除此之外你还要详细的了解如何将NSData转换成各种各样的数据或者文件如果你还不知道该怎么做我这里实在帮不了你,因为我总不能吧多如牛毛的情况都列举在这一篇文章中吧,要知道我每篇文章的篇幅都够长了。。。不过也别因此而气馁百度和谷歌肯定可以帮到你~

接下来我们再看看“邮递员的委托”,嗯一个socket的对象,一个tag嗯,没错,哎哎,慢着,好像哪里不太对啊,我来看看,哪里不对呢,哦对了!发送的数据呢!怎么没有!哎也不对。。。明明是我自己发的数据我还要来干嘛,有了工号我不就知道发送的是什么了么。那是哪里不太对呢。。。哦!是名字!我们的数据传输来说接受可以是读取read而发送通常我们应该写成Send一类的单词,为何这里是Write?写入?没错就是写入,向TCP的通讯流之中写入数据。TCP通讯协议是一个基于字节流的运输层通信协议,其数据传输的形式也是以流的形式提现,而我感觉在使用GCDAsyncSocket的过程中我们可以很好的体会到流的概念,首先来说为什么这种TCP的这种传输形式要叫流而不像UDP中的那样叫做包?流之中又写入和读出的概念,我们可以把整个TCP通讯的连接看作为一条无水的河流,当然因为他没水所以你可以称它为沟,而向其写入数据即是向河流注入水,被写入的数据会向水一样流向连接的另一端。读即是从河流中取水,只要读得动作在继续,并且河流之中有水,那么我们就可以不停的取到数据,不论是河流之中有水你确没有去读亦或者是你去读了而河流之中没有水都会引发看起来完全相同的反应就是没有数据返回,所以在很多时候我们要处理更多的关于接收数据的逻辑的处理。正如我们目前使用的方法就是一种比较粗暴有效的方法——一旦开启连接读取的动作就永不停歇。

接下来我们还要记住使用TCP流式传输数据时的一个关键性问题,数据是不会自己分段的。没错,就如一次次倒入河流中的水一样,数据也同样会向水一样融合为一个整体,换句话说,数据在TCP中传输本身是没有起始或结尾之分,如果我先向数据流中写入两个人的聊天记录,第一句是“你好”,对方回复了一句“不好”,结果发到了服务器,服务器读取出的信息是“你好不好”,同样类似的情况会发生很多,比我举出的这个例子要常见的多比如我先发了一段音频,又发了一段图片,又发了一段文字,最后服务器接收到了一个带语音和字母的静态图片。实际情况上比我说的要遭的多,因为由于字节之间并没有边界,所以字符、文字、音频,我们根本无法确定他们各有多长,胡乱截取,只会导致无法编码解析成图片、文字及音频,所以如何界定数据之间的边界是你开始使用TCP协议之后又一个问题。你可以使用一个固定的字节数组组合来区分开头以及结尾,也可以将所有的字符串都添加一个特殊的界定字符来区分不同的命令与操作。

如果看到这里的看官有心使用GCDAsyncSocket去编写了一个服务器端,并且使用它来接受客户端的数据,比如传输了一些音频,图片等从字节单位看来将会不小的长串数据的话就会发现,服务器端接到的程序是一段一段的,没错,但我没有欺骗你,TCP协议并不会区分你发送数据的头尾,被划分为段知识GCDAsyncSocket为了保证在并不通常的移动互联网之中一样可以安全的传输数据,于是将你所有写入到流的数据都一分割为一段一段的内容,所以请正确理解我在上一段开头所说的“数据是不会自己分段的。”这句话,不要较真哦亲~

写到这里,GCDAsyncSocket的基本操作及其核心思想就全部写完了,对于思想部分皆为笔者本人个人理解,若有缺少或意见不同之处,欢迎交换意见相互学习,感谢您的阅读。

IOS、安卓IM语音聊天开发初探部分心得——网络基础篇

今儿是个还债的日子,没错,承诺了许久的网络传输篇虽然没有千呼万唤,不过我还是厚着脸皮始出来,继上两篇文章总结了一下开发IM语音功能时所遇到的音频问题,而今天就让我们来看看这个让我们看似近在眼前,确始终犹抱琵琶半遮面的网络传输吧~不过在开始我先要提醒一下诸位看官,我们的本章的内容中只是介绍网络的基础只是以及网络协议部分的知识,针对于如何在IOS下应用使用各种协议进行开发,我们将在IOS网络开发应用篇中详细的讲解,或许对于几千字的纯文字描述来说,讲解各种协议以及一些网络基础知识会显得非常枯燥,但相信我,这几千字的文章中是你最易于理解最全面最值得你品读的,关于一个程序所应具备的互联网知识。

网络一词早已不是什么新鲜话题,不要说来看本文的技术型看官们,就连个小学生嘴里都能冒出几句http,tcp等网络协议的名称,可网络是怎么传输的,协议又是干嘛用的?恐怕这一问就要从念叨名词的受众人群中砍掉绝大部分的回答者了。没错从开头看来大伙应该就明白了,笔者又要从远古时期开始讲解,别嫌我烦,做学问要刨根问底,没有个打破沙锅问到底的精神,就做不成大学问。现在这个时代,是知识爆发的时代,也是知识竞赛的时代,你懂个浮皮潦草,别人都懂没意思,想要出类拔萃,就要为人所不能为,知人所不知,方可凭其一身学识,立一方事业。好了跑偏的话题到此为止,接下来,就让我们从“远古时期”一步步来理解网络传输的概念、原理、最终到如何善用。

在计算机领域中,网络就是用物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的。我们用直观一些的白话来说,可以认为是看官与我之间架起一根管道,而通过这个管道把某个物体从一端仍到另一端去,这期中所用到的道具、动作以及双方的通知准备就是计算机网络运行的基础模型。计算机网络的创造者也是人,他们在创造这个跨时代产物的时候也是通过自身常识来判断和设计的,或许这个架起管道的实例并不恰当或具体,不过简单的动作往往更能让人容易理解。从计算机的角度说,计算机网络常用的传输模式是遵循网络七层协议(OSI),而这个协议就是将这个简单的过程复杂化,以达到很多简单过程无法达到的理想效果。说实话如果可以,我一直再绞尽脑汁改如何避开OSI来继续讲解,因为他太底层太复杂并且作为我们程序员并不需要取完全了解它,最重要的是。。。说来惭愧,笔者也不是那么了解这个七层协议,无法讲解的面面俱到,但是,想到下面对于tcp、udp以及http等常用协议的讲解,又不得不提到那么一点,所以我在此设下伏笔,稍后我们会略有涉及,但出于不要误人子弟的中心思想,本文不会详解,如果又感兴趣的看官自行询问度娘,作为一代傲娇弱受,她可谓是上知天文下晓地理,而对于网络七层协议她更是专家中的专家

如果说网线、路由、网卡等硬件设备是我们之前所提到需要传输时架起的管子,那么作为程序员,我们更应该关注的问题应该是如何再错综复杂的管子之间找到要仍的那一根(要知道因特网连接的计算机是数以亿计的!),如何告诉对方我们要扔出物体了,如何扔出我们的物体,以及如何接到这个物体。以不至于东西仍错了管子误伤到无关的路人,或是东西已经扔到对方脸上,他还不知道是什么。或许真正的人不会那么迟钝,因为人是神奇的天作之合,最不可思议的大自然结晶,而计算机则不然,如果管子另一端是犹如计算机的机器人,那么你要是不以他理解的方式告诉他一下,真的就会砸到脸上都木有反应啊!

没错,将上面一段话用稍显学术点的话语总结起来就是,数据行驶在路由、网卡、网线、无线信号之上,而我们程序员要做的是在数据出发前,出发后,以及接收前和接受后所做的一切准备、判断、解释、执行、保存等工作,这些工作可谓繁多复杂,无规矩不成方圆,如果每个程序员都按照自己想法去编写,那么我想我在MSN上从这段发送一句你好之后,你在另一端可能看到的将会是我问候你家庭成员的肮脏语句,那么….后果将不堪设想不对么….为了避免这样的错误发生,为了让苍老师的种子总是可以安全的发送到下一位基友的手中,并且保证他下载的不会是金刚葫芦娃1080P的全集,于是众多的网络协议诞生了。

这里我们来深究一下,为什么网络协议要叫协议?这个名字让众多刚接触的人感到高不可攀,难以理解,简单来说,就是产生了虽但厉的赶脚!回到正题,为什么网络协议不叫网络黄金合体?不叫网络十万个为什么?不叫网络布拉布拉得痛呢?我们接着从现实的事物中来体会协议二字的意义,如果我现在接一个盖楼房的项目,那么雇主要跟我谈一个合同,从哪天到哪天让我去招工,哪天到哪天开始动工打地基,哪天到哪天盖楼,盖到什么时候结款。那么这样一个流程就是一个协议的达成。我们双方遵循协议的规定,按照协议中制订的计划一步步完成。如果我在招工的时候自己跑去挖地基了,挖地基的时候又想要开始收钱,那么雇主会一个嘴巴把我扇回去招人,等到盖楼的时候,我发现地基还没挖完然后挖掘机等机器已经不存在了,于是我只能带着我刚招到的工人用双手刨地基了。。。到最后就是整个工程被我弄得乱七八糟。没错,互联网协议虽然功能大相径庭,但是总的说来思路是一致的,我们该在什么位置做什么事,这就是协议所规定的,我们要做的是先按照需求选定协议,再按照协议的规范一步步将自己的需求完成,那么终于改说一下协议都有哪些了。

好吧,我们就先说一点我们平常常见的来举例。TCP、UDP、FTP、HTTP我相信这些名词大家早已耳熟能详,但是,我首先要提醒各位的是,别光看他们的名字都是XXP或者是XXXP,并且都名字后面都加上了协议就把他们归为一类,他们有着本质的区别,具体的说,TCP、UDP是同一类,他们是位于网络七层协议中的第四层传输层,再准确一点他们是完成第四层传输层所指定的功能,也是位于我们计算机编程人员所接触到的网络七层协议中的最底层(前三层由硬件构成),而FTP与HTTP他们完成的是网络七层协议中第七层也就是最顶层的应用层。还要提醒大家的是,虽然从字面上看第四层与第七层相距甚远,而实际上,他们的跨度不是很大,更并非风马牛不相及,相反他们是紧紧相连的,比如,FTP其实就是基于TCP/IP协议而实现的文件传输协议。

我们从深到浅从计算机网络是什么说到了网络协议是什么有哪些,接下来我们需要换个顺序,从浅到深,依次讲讲今天说到的这4个协议,第一个协议,我们先来说说我的诸位同事——php程序员们所最常接触的http协议。

Http协议,全称hypertext transport protocol, 中文名称是超文本链接传输协议他详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。他是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。他诞生于上世纪九十年代初期,最初被广泛应用的是http0.9,但是它最为知名并且被沿用至今的就是http1.1。

http的特点主要由以下4点较为突出。

1、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

2、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

3、无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

4、无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。

简单的来说,http协议架起的就是一根用户和服务器之间的单向请求管道,用户可以随意向服务器访问,并且要求服务器返回数据,但是并不允许服务器通过相同的方式,向客户访问,这种机制保证了客户端与浏览器单次通话的效率,但是也存在着对于开发者而言不够便捷的问题,当然现如今我们已经可以通过很多技术手段来达成服务器的主动相应,但是,这并非http本身具有的特性。同时Http协议的连接可以理解为即时性的,他每完成一次操作请求,需要重新进行查找、准备、传输、响应、回传、关闭等这个流程步骤,而不能像tcp协议那样一次性连接之后可以持续的收发请求即时做出反应,等所有操作完成再关闭连接。所以,其实你在浏览网页的时候,输入一个网址或者点击一个连接都是重新向服务器发送请求并要求返回数据,这样的效率可以说从原理上来讲并不高效,但是现在我们可以通过诸如缓存等方式来减少这种操作的弊端。Http协议中总共定义了八种方法来表明指定资源的不同操作方式。也就是对某个网址下的网页,或者某个URL下的文件的八种不同操作。

OPTIONS

返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送”*”的请求来测试服务器的功能性。

OPTIONS请求方法的主要用途有两个:

1、获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。

2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。

HEAD

向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。

客户端可以使用HEAD请求来收集相关信息以确定如何操作该资源.例如,在IE中,如果一个OBJECT元素缺少TYPE参数,浏览器就会发送一个HEAD请求,目标URL为这个OBJECT元素的SRC属性指定的URL.然后浏览器就能够根据响应中的Content-Type头知道这是哪种类型的OBJECT.

GET

向指定的资源发出请求。获取一个文档,大部分呗传输的浏览器的html,images,js,css,……都是通过get方法发出请求的。它是获取数据的主要方法

注意:GET方法不应当被用于发布命令,更新数据库,或任何明确的客户端动作。其中一个原因是GET可能会被网络蜘蛛等随意访问。

POST

向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。

关于GET请求以及POST请求的安全问题

所谓安全,意味着操作用于获取信息而非修改信息。换句话说,GET请求一般不应该产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。这里安全的含义仅仅是指是否修改信息。

接下来,POST的安全性要比GET的安全性高。注意,这里所说的安全性和上面的GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不做数据修改,而这里安全的含义是真正的Security的含义,比如通过GET提交数据,用户名和密码将铭文出现在URL上,因为登陆页面有可能被浏览器缓存,其他人查看浏览器的历史记录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击,虽然我不知道它到底是什么攻击。。。喜欢研究“如何不使用菜刀做菜而去杀人”的童鞋请自行百度“跨域伪造请求”。

PUT

通常用于向服务器发送请求,如果URI不存在,则要求服务器根据请求创建资源,如果存在,服务器就接受请求内容,并修改URI资源的原始版本

关于POST与PUT的区别

POST请求的URI表示处理该封闭实体的资源,该资源可能是个数据接收过程、某种协议的网关、或者接收注解的独立实体。然而,使用PUT请求对服务器操作的情况下,如果是要上传文件,则需要确定服务器上尚无重复的文件名,并且生成URI而后提交请求,如果该文件已经存在,则会出现被替换的情况,即使服务器做出判断判别出当前文件已存在,针对PUT请求,服务器也无法修改PUT请求当前所要操作的URI,智能拒绝用户的请求并且让用户重新发送该请求。

DELETE

请求服务器删除Request-URI所标识的资源。

在服务器接收到DELETE请求对某个URI的删除请求后,服务器并不会马上对其进行操作,即使客户端接收到的了200 OK信息的返回码,也只是代表服务器已经成功接收到该请求,具体操作则由服务器端完成。

TRACE(追溯)

回显服务器收到的请求,主要用于测试或诊断。

TRACE和TRACK是用来调试web服务器连接的HTTP方式。

支持该方式的服务器存在跨站脚本漏洞,攻击者可以利用此漏洞获得合法用户的私人信息。

CONNECT

HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器

以上就是Http协议的八种请求,也是通过http协议与服务器沟通的所有方法,如今http协议被大量的应用在万维网领域也就是我们常说的web开发之中,但不代表http协议只能使用在web端,比如手机应用之中,也存在很多使用http协议与服务器建立沟通的。比如比如百度地图API,新浪微博App,比如人人网手机端,比如我们的三姑……

首先,我需要感谢看官您读到了这里,这属实不易,我想如果您真的是用心读到此处估计会问,你洋洋洒洒写了2000多字的http协议,可它跟你之前所说的架起一根管道对仍实物的比方好像完全没什么关系,bingo!全中!就是这样,http协议的运作模式的确和之前的比喻不太相符合,如果硬要做一个比方的话,那么服务器就相当于棒球中的接球手,而客户端则相当于投球手,每次当客户端投出一个球之后,服务器都会告诉你这是个好球还是坏球,当然也有可能是被本垒打了。。。之所以要把http放到第一个还讲这么多,是因为它确确实实是我们在日常应用中最容易接触到的协议,比如你输入任何网址之前先打上的“http://”。好吧,让我们回到讲解http协议之前,也就是管道对仍物品的例子中,没错,接下来我们要说的就是与此例非常相近的FTP协议

FTP协议全称File Transfer Protocol,中文名称文件传输协议。它使用 TCP 生成一个虚拟连接用于控制信息,然后再生成一个单独的 TCP 连接用于数据传输。文件传输协议是TCP/IP网络上两台计算机传送文件的协议FTP是在TCP/IP网络和INTERNET上最早使用的协议之一,它属于网络协议组的应用层。FTP客户机可以给服务器发出命令来下载文件,上传文件,创建或改变服务器上的目录.

没错,就如同他的名字一样,FTP是专门用于文件传输的协议,而就像我之前说过的那样它的底层是基于TCP协议的。与http的模式不同,如果想要通过他来完成数据的传输,那么我们首先要做的第一步是先建立连接,而非直接对某个服务器发送请求。FTP有两种使用模式:主动和被动。主动模式要求客户端和服务器端同时打开并且监听一个端口以建立连接。在这种情况下,因为必须开放一个随机的端口以建立连接,当防火墙存在时,客户端很难过滤处于主动模式下的FTP流量。所以,创立了被动模式。被动模式只要求服务器端产生一个监听相应端口的进程,这样就可以绕过客户端安装了防火墙的问题。

 

一个主动模式的FTP连接建立要遵循以下步骤:

1.客户端打开一个随机的端口(端口号大于1024,在这里,我们称它为x),同时一个FTP进程连接至服务器的21号命令端口。此时,源端口为随机端口x,在客户端,远程端口为21,在服务器。

2.客户端开始监听端口(x 1),同时向服务器发送一个端口命令(通过服务器的21号命令端口),此命令告诉服务器客户端正在监听的端口号并且已准备好从此端口接收数据。这个端口就是我们所知的数据端口。

3.服务器打开20号源端口并且建立和客户端数据端口的连接。此时,源端口为20,远程数据端口为(x 1)。

4.客户端通过本地的数据端口建立一个和服务器20号端口的连接,然后向服务器发送一个应答,告诉服务器它已经建立好了一个连接。

被动模式FTP:

为了解决服务器发起到客户的连接的问题,人们开发了一种不同的FTP连接方式。这就是所谓的被动方式,或者叫做PASV,当客户端通知服务器它处于被动模式时才启用。

在被动方式FTP中,命令连接和数据连接都由客户端发起,这样就可以解决从服务器到客户端的数据端口的入方向连接被防火墙过滤掉的问题。

当开启一个 FTP连接时,客户端打开两个任意的非特权本地端口(N > 1024和N 1)。第一个端口连接服务器的21端口,但与主动方式的FTP不同,客户端不会提交PORT命令并允许服务器来回连它的数据端口,而是提交 PASV命令。这样做的结果是服务器会开启一个任意的非特权端口(P > 1024),并发送PORT P命令给客户端。然后客户端发起从本地端口N 1到服务器的端口P的连接用来传送数据。

对于服务器端的防火墙来说,必须允许下面的通讯才能支持被动方式的FTP:

1. 从任何大于1024的端口到服务器的21端口 (客户端的初始化连接)

2.服务器的21端口到任何大于1024的端口 (服务器响应到客户端的控制端口的连接)

3. 从任何大于1024端口到服务器的大于1024端口 (客户端初始化数据连接到服务器指定的任意端口)

4.服务器的大于1024端口到远程的大于1024的端口(服务器发送ACK响应和数据到客户端的数据端口)

好吧,我知道以上这些虽然足够准确无误,但是它会让人感觉头晕目眩,什么是端口?哪来的PORT和PASV?让我们用通俗一些的话语来重新描述一遍整个过程。

首先,FTP下载模式的确立需要一个FTP服务器和一个客户端,主动模式中,客户端会按照指示找到一个FTP服务器,如果连接成功了,客户端会先向服务器端发送一个指令,这个指令包含的内容大致是你的所在位置。

接下来就像我们之前举的例子一样,当管道架到另一头之后,对方会告诉你,你的管道已经在我手里了,可以准备发东西了。此时的FTP服务器就会回头跟客户端打个招呼,“嘿,兄弟,你找到我了”,而当前这根管道并非我们用来互扔物品的管道,他用来传递一些命令,这就像你发了个不会上门送件的快递给朋友,与此同时你还要先打电话告诉他一下,“别忘了取邮局取快件”那么现在这根管道就相当于你的电话。你可以在其中传达各种信息及命令,比如你想要通过哪个物流来完成这次快递,顺丰还是圆通?再比如你要传输的文件是什么,以及你是谁等等等等。

还记得我们第一步中发给服务器的那个地址么?没错是你的地址,当服务器向你打过招呼后会紧接着向你之前所给出的地址发出一个连接,这个连接管道就是用来传输文件的管道了,而作为客户端在成功连接之后你也应该用同样的方式回头再打个招呼,“嘿,你真聪明,没错管道送过来了!”而这就是整个主动FTP连接的建立过程,在这之后你就可以与连接完毕的FTP服务器进行文件收发了。但是我们的过程中有个让人不太满意的地方,是的,当服务器想你的机器进行访问的时候,可能你还没接到管道,就被自己家的门卫给轰跑了,因为门卫觉得他来历不明,竟然还要想连一根管子进小区,没错像这样可恶的家伙可能你的防火墙门卫每天都会轰出去很多个~因为有很多家伙想在你不知情的情况下通过一根根管道在你的家中行窃!

当然问题都会又解决的方法,这就是被动FTP,它与主动FTP的不同的地方就是,你在连接服务器之后并不会发给他地址,让它直接来找你,而只是告诉他“嘿,伙计,我可算找到你了,等下哈,我马上把管道牵过来!”然后服务器就会乖乖的把一个约定地址回发给你,当然这个地址会与你刚找到他的那个不同,那是一个准备要简历传输管道的地址。接下来客户端要做的就是按照接到的地址再去连接一次服务器,这样传输的管道就架好了,同时你的门卫也不会像对待那些歹徒一样赶走服务器了。

好了,FTP就介绍到这里,或许我换了一种解释方法之后你明白了FTP是怎么运作的了,可是依然不了解什么是端口,没关系,接下来我们将要要更深入一层,解一下TCP/IP协议,与UDP一样它是位于软件所涉及到最低层的网络协议,而在这个过程中,我不只要告诉你什么是端口号,还要告诉你很多FTP和TCP他们最大的区别。

TCP全称Transmission Control Protocol中文名,传输控制协议 ,TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。而我们之前讲到的TCP/IP准确的来说是不完全相同的,因为TCP只是一部分,而后续的IP是另一部分

如果你还听说过TCP/IP4,TCP/IP6的话其实别把他们之间的TCP分开看因为那是一个东西,不同的其实是IP4和IP6,IP4中规定IP地址长度为32,即有2^32-1(符号^表示升幂,下同)个地址;而IP6中IP地址的长度为128,即有2^128-1个地址。说实话我们或许不应该谈论太多关于IP的内容,所以我只把IP4和IP6之间的区别列出了一点,因为IP他更倾向于网络七层协议中的第三层,他的作用就是用于表示每台计算机,在一个局域网或广域网或任何一个网络中的物理地址,相当于一台计算机的门牌号,当然这是电子门牌号,所以设置与更换起来可能让你觉得没有实际的门牌号那么困难,起码你不用找有关当局申请或协商,但是作用其实是一样的——都是让别人来找到你的位置。

好了关于IP我们就说这么多,现在回头我们来说说TCP,前面说过,TCP通讯协议是面向连接的,可靠的,基于字节流的运输层通信协议,那么这一连串的名头都代表着什么?我们逐一讲解。

首先要说到的就是面向连接,说到这个名词我们就得说说与它向对应的一个名词面向无连接, 其实我们通过http与FTP就可以看出二者的区别,当然我这么说肯定会挨喷但是为了有助于各位理解我还是要说,http起码从操作上来讲,让你感觉,不管服务器是否开启,是否接受,我都只管发送我的请求,并不需要先向服务器确认什么,即时服务器是关闭的,没有启动的,或者是网络断开的,对于我们客户端来说该发送数据依然可以发送,当然不过是服务器接不到嘛。但是FTP则不然,我们在真正发送数据之前需要先跟FTP服务器进行连接通信,当一系列的通信完成之后我们才可以做一系列传输数据等工作。这就是二者的区别。但是我必须要澄清,Http协议的底层虽然不是全部,但是依然主要依靠TCP的面向连接来完成的,而真正面向无连接的协议是UDP,关于这方面的知识,有兴趣的童鞋可自行百度。

面向连接和面向无连接之间二者的区别我们理解了,可以确定的是,面向无连接协议传输速度要比面向连接的传输速度快很多,非常多,但也仅限于你的网络带宽之内,同时他还存在着很多不安因素,就像之前的比喻,如果我把管道加载一个机器人面前并且毫无前兆的就通过管道向他仍各种物品,那么结果就是砸到他脸上他都会置之不理。而再实际开发中,诸如此类的问题就如繁星一样,躲到你忘记几个都不会发现。。。所以说TCP协议是可靠的。

最后我们来说说什么是基于字节流的,字节我们很好理解,计算机中一切的存储内容,不论是内存还是内盘之中的存储信息都是通过01机械码来实现的,而每8位的01机械码所组成的就是1字节,以此向上的单位千字节就是KB,1024字节等于1KB,当然在不同系统下换算进制不一样,比如MAC系统下就是1000进制,而之后的MB,GM,TB我相信你们都懂的- -而流就是不包含边界数据的连续数据流,字节流我们从字面分析来看,一长串以字节为单位组成的不包含边界数据的连续数据流。

如果我们要使用TCP协议来传输数据的话就得先确认一个需要链接的对象,请注意我这里的用词,并非服务器也非客户端,没错TCP的连接建立,从协议本身来讲并没有服务器或者客户端一说,他只是将两个IP地址的计算机相连接起来,而我们需要的知识对方的IP地址,可是问题来了,或者我的服务器上并不只是运行一个服务器端程序,有人访问我的时候我该如何区分这些访问信息分配给不同的程序呢?没错,这里我们就用到了套接字socket它与我们之前总是提到的端口号密不可分。

socket的英文原义是“孔”或“插座”。作为4BDS UNIX的进程通信机制,取后一种意思。通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。常用的socket套接字有3种,而我们通过TCP协议所使用的就是流套接字(SOCK_STREAM)。而我们之前所说的端口号就是给予不同套接字所绑定的唯一的编号ID,取值范围再0-65535之间,而前1024个端口是被各系统所占用内部定义使用的换而言之就是我们在开发应用程序分配端口号是要分配编号在1024以上的。而我们之前再FTP举例中所提及的20端口号和21端口号就是特列,他们就是被系统所分配专门用于FTP传输的端口号。

通常一个基于TCP协议的客户端与服务器端的流程如下:

  1. 服务器程序开启,同时监听某个指定好的,大于1024的端口号
  2. 客户端启动,并且按照服务器的IP与端口号向服务器访问
  3. 服务器接到链接请求,链接接连成功,并且向客户端返回一个链接成功的返回包

以上就是一个服务器与客户端之间最简单的连接建立的过程。

在创建连接之后我们要做的就是开始收发数据,连接一旦创建第一件事情就是开启一个无线性的循环/等待的的过程,不论是客户端还是服务器端都要让socket不停的接收数据,哪怕根本没有数据。这样是为了再你需要向对方发送数据时,你只需要将需要发送的数据写入数据流,那么对方就可以读到你所写入的内容了,别高兴的太早,这一切并没有看起来的那么简单。

按逻辑来说在建立连接之后,除非手动关闭,否则连接理论上与程序逻辑中会一直判定为该连接存在,但实际上我们需要通过很多手段来确认连接是否正常。通常我们使用心跳包的方式来确认连接的正常性,所谓的心跳包就是每间隔固定时间,从客户端向服务器端发送的一个固定的数据包,服务器则会根据受到包的内容判断出这个数据包是个心跳包,同时也返回给客户端一个信息,以让客户端得知连接正常无误。以继续进行连接操作,又很多情况会导致程序逻辑上的连接状态与实际的连接状态不同,所以当客户端长时间接收不到心跳包的返回时我们就需要对程序的逻辑做出一定的修改,以避免严重错误的发生。

除此之外,我们还要判断数据是否完全发送/接受,而且对于数据的处理也会面临很多问题,因为TCP协议是基于字节流传输的所以数据并没有开头与结束之分,甚至如果一口气连续发送几个文件的话,我们在另一端接收到信息时甚至无法分清有几个文件?他们都多长?这些都不知道,只是收到了一长串很长很长的字节流。

就如上面所说的,使用TCP协议是通过系统最底层的网络传输协议来传输数据,如果说http协议和ftp协议是定义了如何接收信息和如何区分信息以及传输信息的格式。那么tcp完成的就是确立目标位置,并将数据统一化之后发送到目标位置。直接通过tcp协议进行开发可以达到最理想的面向连接协议传输效果,相对而言的我们需要付出更多的精力去编码,用大量的代码来维护链接的安全,在保证他的健壮性的同时,还要设定数据的分割以及接收的方式,等等等等,好吧,如果我说道这里你就觉得复杂了,我只想提醒你,后面还有UDP呢。。。。。。

好了今天天的内容就到这里吧。。。已经洋洋洒洒写了近万字。。。我如果非要把UDP也讲完,估计也没有童鞋能够看完了,对于UDP我已经不打算再此为大家继续讲解了,因为它的内容其实前面我们已经提得差不多了,而关于具体的详细内容,请有心得童鞋自行百度吧,我们下篇文章将介绍,如何在IOS系统下使用http和tcp两种方式的网络传输。好吧各位看官,我们下期见。

Mac客户端CentOS服务器 SSH免密码登陆

在学习GIT服务器搭建过程中,需要用到SSH进行客户端与服务器的连接。

为了在使用SSH登陆服务器时省去每次输入密码的麻烦,所以弄了一下SSH免密码登陆。

1 在Mac客户端命令行生成公钥和私钥

# cd ~/.ssh

# ssh-keygen -t rsa

之后回车两次,注:(Enter passphrase (empty for no passphrase): 可以设置密码)

结果生成两个文件id_rsa(私钥)和id_rsa.pub(公钥)

2 发送公钥到CentOS服务器端

# scp id_rsa.pub user@ip:~/.ssh

3 登陆CentOS服务器端,设置公钥文件

# ssh user@ip   注:此时还是需要输入密码

# cd ~/.ssh

# cat id_rsa.pub >> authorized_keys

# chmod 600 authorized_keys   注:必须设置成600

4 在Mac客户端输入# ssh user@ip,即可无密码访问。

附:RSA算法http://baike.baidu.com/view/10613.htm

如何才能在appstore发布你的应用 ——Xcode4.6原生ipa提交审核之最详尽步

经过几月的编码,终于在iTunesStore上提交了三姑微博的审核,之前处于破解框架开发状态下的我对于苹果对应用管理的机制可以说是两眼一摸黑。。。但是好在,在Chrome浏览器强大的翻译功能支持下,最终成功的提交了审核(虽然还尚未通过审核。。。)

其中在网上寻找教程的时候由于编译环境版本的差异,走了不少的弯路,为了避免后人同有此遭遇,遂书此文以供参考。但是在此之前我希望各位看官在开本文之前请先忽略它的长度,并且切记,这是个麻烦事,别怕费劲耐心的跟着我们做到最后你会成功提交应用的。

首先你需要确定你有一个mac系统的电脑,而不是虚拟机,从某篇文章上看到了略述此问题,如果是虚拟机可能会出现一些的问题,当然由于有着mac系统在手鄙人没有详细观看,需要此方面的资料的话还请百度。

其次,是素材的准备,

第一,图标:填写应用提交信息的时候,需要一张1024*1024的大图标,此图标需为jpg格式,DPI72像素以上,建议设置的更高些,150~200左右,72DPI的图标在你填写资料的时候并无问题,问题在于你缩小该图标使用在应用中的图标也有要求,必须为57*57像素,此时如果你的DPI过低,在iphone的屏幕上就会出现马赛克的现象,iphone对于图片质量的要求非常高。

第二,应用截图,对于应用截图的要求,苹果的要求具体是这样,3.5寸手机屏,4寸手机屏,以及ipad屏的截图三种截屏加起来只需要至少一张,也就是书你填写资料的时候保存的截图可以只有一张截图。而详细的情况是要看你的应用,比如你的应用支持3.5寸的手机屏和Ipad屏那么在准备截图的时候你就必须要准备至少两张。每种支持的屏幕一张。此处还有一点需要特别注意,就是在使用ios SDK6.0以及Xcode4.5以上的编译环境制作应用时,你会经常看到一个警告提示,此提示只要双击根据弹出的对话框就会自动解决,其解决方法就是在你的项目中加入一张名字为,Default-586@2x.png的纯黑色图片,请别忽略这张图片,如果你是使用的Xcode4.5以上的编译环境我建议你此时也检查一下项目中是不是有这么一张图片,如果存在这张图片,那么编译器就会认为你的项目是支持Iphone5的驴脸屏的,而换到当前要提交审核的情况下来说,你填写信息时是不会有任何错误提示的,在你上传Ipa后,并且你恰巧没有想要适应凤5驴脸屏的打算下,会发现你的应用状态并非在审核中,而是提示你缺少了素材,因为你没有上传凤5驴脸屏的截图。好在解决方法不难,只要删除掉这张让人不知该爱该很的Default-586@2x.png就好了- –

关于图像素材的准备,就到这里,可以了,我们接下来就到苹果开发者中心看看,一步一步的来提交我们的应用。后面需要的主要到的问题,我会在遇到时提醒。

好吧,现在如果你是一个破解了Xcode框架面证书时机调试,或者从开发之初就一直选择模拟器编译的家伙,那么恭喜你,你遇到的第一个问题就是,开发者中心在哪?我的天……太可怕了……我们原来还不知道要该在哪里工作,可应用已经都做出来了……没关系,打开百度,度娘会告诉你你想知道的一切,前提是,你发问的方式正确。告诉度娘,我们要去“苹果开发者中心”他会把你要去的地方显示在搜索结果中非推广链接的第一个。

现在我得提醒你一下如果你没有chrome浏览器,又恰巧英文烂的一塌糊涂,那么你最好现在先问问呢度娘应该在那下载chrome,否则打开了开发者中心你也会一头雾水,没错,全是你从上学起就恨之入骨的24个老朋友的规律编程集合体。什么?你说26个?好吧,管他呢,如果你用到了这里的帮助,我猜测你都应该和我有一个共通点就是跟他们20几位都不太熟。

为什么要用chrome浏览器,因为它的翻译功能是在太强大了!强大透了!百度翻译那种烂货完全没法相比的强大,基本上有了它的翻译你可以完全无障碍阅读整个苹果开发者中心的所有页面了。当然有的时候你也需要一些想象力……

好吧,我们来到了一个有点陌生的网站,恕我直言,如果你想要搞IOS开发或者是mac开发,那么你早就该来这了,多熟悉下没坏处,别跟着教程走,多去点点看看,反正有度娘,你可以随时再次找到主页。另外提醒您一下,如果你想在appstore上架您的应用,必须要有一个开发者账号,个人开发者账号99美元一年,企业账号299美元一年,如何申请,本博客内另有NickLiu大师的有文章介绍,所以此处不再赘述。

继续我们的步骤,点击主页的iphone开发者中心。当然这是翻译过后的内容,搞不定翻译的,请先别继续了后面更难,真的。。。

进入Iphone开发者中心之后请先点击网页上放一个蓝色的小按钮进行登录。在Iphone开发者中心里可有着最新xcode编译环境的和SDK以及各式各样的应用下载,你可以找到你想用的一切原生开发工具。为什么要说这个?因为如果你之前的xcode编译环境不幸的被你免证书调试修改了文件,你最好再下载一个新的编译环境。

接下来别忘了我们要干什么,没错上架应用。再网页最上方会有翻译过来的一个菜单,虽然它不太起眼,但是你找到它应该也不难,在此处打开会员中心。

接下来进入的网页会有6个主要项目,分别是,开发者中心,IOS的置备门户,AppStore的资源中心,iTunes连接,苹果开发者论坛以及开发人员支持。

此时我们先进入IOS的置备门户,此项下只有一个连接你应该不会搞错~

我们在此处需要创建证书、应用ID等,如果配置,在本博客NinkLiu大师的博文中也有所描述,但是我们这里说到的应该不太一样,别弄混了朋友,因为他只是要调试,我们要的是发布!

创建证书请求CSR步骤如下:

设置OCSP和CRL为关闭状态。

Mac OS 中,打开应用程序,找到 钥匙串访问(Keychain Access)工具打开主菜单- 证书助理(Certificate Assistant)-从证书代理请求证书(Request a Certificate From a Certificate Authority)输入iDP注册时的email,用户名自定义,选择“存储到磁盘”,选择‘Let me specify key pair information’。

选择保存路径,证书请求创建成功。
接下来就可以登录iDP Portal提交证书请求了,到这个页面
http://developer.apple.com/iphone/manage/certificates/team/index.action 

点Development,‘Request Certificate’,然后点Browser,添加刚才生成的证书,点submit。

点击Approve,一分钟后会生成一个.cer文件。

好的我们的证书创建完成了如果你还没能创建出你的证书,请百度其他证书创建的教程,由于时间问题,所以其实以上创建步骤笔者也是百度上复制粘贴而来……深感惭愧……

接下来我们回到IOS置备门户的主页。在左侧的菜单中点击“应用程序的ID”当然这也是翻译后的显示。打开后在菜单右侧的页面的右上角有着一个按钮上书“新的应用程序ID”没错你真聪明猜对了,点击它。

此处需要你填写两项,第一项是输入一个描述,这里随意,你记得是什么就好,但是只能输入英文字母别妄想使用中文了。

接下来还需要填写捆绑标识符,这里需要注意了,此处必须和你的项目中填写的唯一标识一致,就是在你创建项目时所填写的com.xxx.xxxxx,如果不记得也没关系,打开Xcode,点击你的项目—〉TARGETS—〉info—〉Bundle identifier的值便是我们要填写在此处的捆绑标识符,复制到此处粘贴。填写后submit提交。

再从左侧菜单栏点击“供应”,然后在右侧窗口中点击分配选项卡,打开选项卡后,在选项卡内部右上角,点击“新的配置文件”按钮,分配方法选择“应用程序商店”,在配置文件名称中输入一个名称,应用程序ID中选择刚刚创建的应用程序ID,点击submit提交按钮后创建完成,此时如果看到刚刚创建的配置文件的状态不是“活跃”的话就等1到2秒钟时间,再点击一下分配选项卡,刷新一次就好了。

此时需要创建的内容已经全部完成了,现在将刚才创建的证书、和在分配选项卡内创建的配置文件下载下来。,出于“活跃”状态后操作栏会出现下载按钮。

双击运行下载的文件,就会将证书和配置文件导入系统和xcode中,此时如果你使用过面证书编译的话,建议使用重新下载安装后的Xcode编译器。点击项目—〉TARGETS—〉Build Settings找到CodeSigning Identity选项,点击展开,找到和你刚刚创配置文件对应的选项选中设置。

点击Run按钮左侧的项目名,也就是选择测试设备/模拟器按钮的右侧,点击后会展开,选择Manage Schemes,点击左下角Edit按钮,在弹出的对话框中选中左侧菜单栏中的Archive。将Build Configuration设置为Release,点击OK按钮。在Xcode屏幕最上方的菜单栏中,打开Product菜单,点击Archive选项。此时编译器会开始编译项目,时间可能比普通运行时稍慢,不要着急请耐心等待。编译完成后,会自动打开Organizer窗口,并且显示你刚才编译过的项目。点击Distribute按钮,选择第二项,Save for Enterprise or Ad-Hoc Deployment.点击Next按钮,在CodeSigningIdentity选项中,选择对应的配置信息,然后点击Next稍时过后就会编译出ipa文件,并且询问你保存位置,放到一个好找的地方哦,一会要用到的。

回到会员中心,点击iTunes连接下面的“提交和管理您的应用程序在AppStore上。”在接下来的页面中,点击“管理您的应用程序”,在打开页面的下方找到“下载应用程序加载”的连接,好吧,此处chrome翻译的过头了- -,这是下载提交ipa的一个应用程序,可名称被翻译了- -接下来将会下载一个66.6M大小的dmg镜像文件,多么吉利的体积!下载完成后打开镜像双击其中的安装包进行安装。

安装之后,你需要打开你的mac系统盘符,如果找不到,点开Finder,然后点屏幕最上方菜单栏中的Finder,打偏好设置,打开边栏选项卡,将设备中的所有选项选中。关闭偏好设置,你会发现finder右侧中多出了一个XXX的“mac”选项,点中它之后就可以看到所有盘符,其中当然也包括系统盘符,打开系统盘符下的Developer文件夹,打开Applications文件夹,打开Utilities文件夹之后就可以看到ApplicationLoader.app这个应用了。他就是用来上传IPA的,但是现在别着急,我们还需要在iTunes连接也就是网上常说的iTunes Connect中创建应用~

回到网页中的“管理应用”页面也就是刚才下载ApplicationLoader的页面。点击页面右上角蓝色的addNewApp按钮,首先需要选择语言,然后填写您应用程序的名称SKU编号填写刚才我们填写过的那段com.xxx.xxxxx的那串标识即可,捆绑ID中选择刚才我们新配置的ID,,点击页面右下角Continue的蓝色按钮继续。选择上市日期、价位、等信息,请更具自己情况设置。设置完成后继续点击Continue按钮。此页面中所有选项请根据您的应用情况自行填写,如有不明白的信息,请点击后放的问号圆型按钮,即可得到提示,截图、图标等应用信息都在此处添加,注意事项前面已经说过,不再赘述,全部填写完成后点击右下方的Save按钮保存信息。保存信息过后你会发现自己的应用处于准备上传的状态,此时再次打开查看详细信息,在详细信息页面的右上角的Ready to Upload Binary按钮在询问信息项中按照您应用的信息选择单选按钮点击save保存,再点击Continue按钮回到应用信息页面,此时应用的状态时等待上传。

现在暂时最小化网页,我们回到MAC中继续操作。

打开Application Loader也就是刚才安装好的应用,登陆后点击DeliverYourApp按钮,在Choose下拉菜单中选择您刚刚创建的应用,起反应可能有点慢,因为MAC需要加载应用的信息,等待选择完成后,点击Next按钮继续。此时你就会看到自己应用信息了,点击左下角的Choose按钮,选择之前导出的ipa文件点击Open按钮打开。然后点击Send按钮提交应用,此时如果您前面操作无误即可等待应用上传完毕后去网页上查看你的应用信息,已经成为待审核了,如果上传ipa时出现错误,或者在应用信息界面出现错误,请详细翻阅本文提示内容,或经百度查询错误原因。

以上就是提交一个应用到appstore审核的全部过程……没错这的确有点长…4000多字的文章我纯手打出来也不易…现在我已经被累得一个字都不想多打了…诸位我们今天就到这里,再见吧!

Objective-C中的类、对象和方法

类、对象和方法

什么是对象

对象就是一个物件。汽车这个名称就是一个类。

汽车的每个实例都是一个对象。

实例和方法

类的独特存在就是一个实例,对实例执行的操作称为方法。

洗车这个动作,适用于一个实例。

而找出一个厂家制造了多少款汽车则适用于类,所以他是一个类方法。

 

类方法不需要一个特定的实例对象。只是针对于类别的操作,所以我们在使用类方法时并不需要构造一个实例对象。

这种方法在其他语言中又称之为静态方法。

@interface

在定义新类时,首先需要告诉Objective-C编译器该类的父类命名。其次,定义在处理该类的对象时,将要用到的各种操作或方法的类型。在@interface部分中还会列出一些元素,称为属性。

按照约定,类以大写字母开头,这种该约定能使其他人在阅读你的程序时,仅仅通过观察名称的第一个字母就能把类名和其他变量类型区分开来。

命名规则

sum$value   ———————— $非法字符

piece flag    ———————  名称中不允许插入空格

3Spencer    ———————— 名称不能以数字开头

int                ———————— 保留字

除了以上强制的命名的规则(指编译器无法通过的命名),通常为了让我们的代码阅读起来更加便于理解,我们还需要在命名上下一定功夫,有一定规则、规律,如类内属性我们可以统一使用m_开头,全局变量,我们都使用g_开头,这样的命名方式,让我们很容易在代码中区分开很多看起来相似,但是应用位置、作用都不同的变量和方法。

Objective-C中的大写字母和小写字母是有区别的,因此,变量名sum、SUM和Sum均表示不同的变量。

AddressBook————可能是一个类名称

currentEntry————可能是一个对象

current_entry————一些程序员还使用下划线作为单词的分隔符

addNewEntry————可能是一个方法名

确定名称时,要遵循同样的标准,千万不要偷懒,要找能反应变量或对象使用意图的名称,不要去使用中文的拼音代替,虽然这很方便,但是更多的时候这让他人无法理解你的意图,就像使用注释语句一样,富有意义的名称可以显著增强程序的可阅读性,并可在调试和文档编写阶段受益匪浅。事实上因为程序具有更强的自解释性,所以编写文档的任务将很可能大大减少。

类方法和实例方法

开头的负号(-),通知Objective-C编译器,该方法时一个实例方法。除此之外,只有一种选择,就是正号( ),它标示类方法。类方法时对类本身执行某些操作的方法,例如,创建一个新的实例。

在制造出一辆汽车后,引用这个汽车实例时,可能要执行给他加油的操作,这个加油的操作时对特定的汽车执行的,因此,它类似于实例方法。

  1. 返回值

声明新方法时,必须告诉Objective-C编译器该方法是否有返回值,如果有返回值,是哪种类型的值。

如:-(int) currentAge;

指定名为currentAge的实例方法将返回一个整型值。

如果方法没有返回值,则按照如下语句定义:

-(void) print;

这即是声明一个名为print且无返回值的实例方法。

2.方法的参数

-(void) setNumberator: (int) n;

-(void)setDenominator: (int) d;

以上两个方法,他们都是没有返回值的实例方法。每个方法都有一个整形参数,这是通过参数名前面的(int)指明的。就setNumerator来说,因此,setNumerator的声明制定向该方法传递一个名为n的整型参数,而且该方法没有要返回的值。这类似于setDenominator的声明,不同之处时后者的参数名是d。

声明方法的语法:每个方法都以冒号结束,并且这个冒号会告诉Ojbective-C编译器该方法会有参数。接下来,制定参数的类型并将其放入到一对圆括号中。最后,使用象征性的名称来确定方法所制定的参数名。整个声明以一个分号结束。详细函数声明的构造如下图:

[singlepic id=123]

然而实际情况中,我们需要定义的函数可能不只有一个参数,那么我们该如何定义一个多参数的方法呢?

通过列出每个连续的参数并用冒号将其连接起来,就可以定义一个接受多个参数的方法。用冒号连接的参数并用冒号将其连起来,就可以定义一个接受多个参数的方法。用冒号连接的参数将成为这个方法名的一部分。例如,方法名addEntryWithName:andEmail:表示接受两个参数的方法,这两个参数可能时姓名和电子邮件地址,它完整的声明应该如下:

-(void) addEntryWithName: (NSString) name

andEmail: (NSString) email;

在声明时,我们可以把整个函数声明写在同一行中,但是我们并不推荐这么做,因为那样会让你的代码看起来很长,并且很难看出参数的顺序以及参数之间的关系,所以通常,我们在声明函数时将每个参数独立一行,当声明到下一个参数时,则换新的一行,并且所有的参数之间,以冒号对其,这样,整个函数的声明就非常清晰明了了,冒号对其的左侧为函数的名称,而右侧一行为参数的类型以及参数名。这样的格式并不只局限于函数的声明或定义,在调用时我们依然可以这么做,这时一种被很多程序员们津津乐道的命名格式,或许刚开始你有点不适应,但相信我,你会爱上这种格式的。

@implementation

@implementation部分包含声明在@interface部分的方法的实际代码,且需要制定存储在类对象中的数据类型。在@interface声明方法,并在@implementation部分定义他们。

@implementation部分一般格式如下:

@implementation NewClassName

{

memberDeclarations;

}

methodDefinitions;

@end;

NewClassName表示的名称与@interface部分的名称相同。可以在父的名称之后使用冒号,如同在@interface部分使用冒号一样如:

@mplementation Fraction:NSObject

memberDeclarations部分指定了那种类型的数据将要存储到Fraction中,以及这些数据类型的名称。可以看到这一部分放到自己的一组花括号内,通常我们在其中声明一些类的成员变量、枚举等,但是不包括方法。对于类而言,其中的声明表示类的成员。如果你的类将构造出多个对象的话,那么你的每个对象都会拥有各自的成员。Objective-C系统将自动追踪这些实例变量。

因为Objective-C中并没有封装等级,如果硬要联系上的话,那么在此处声明的成员皆为私有成员,因为他没有声明在.h中,也就代表着无法被类外所认识。

 

methodDefinitions部分包含在@interface部分制定的每个方法中。此处的方法与@interface方法的声明使用相同的写法,但是我们并不会以分号作为结尾来结束函数的声明,因为此处我们定义(实作)这个函数——将你要该函数执行的的代码放入一对花括号中。

Program部分

Program部分并基于我个人的理解,他并不在某个类之中。它包含解决特定的问题的代码,如果有必要,它可以跨越多个文件。main函数我想对于学过其他高级语言(php除外- -)的人来说都不会陌生,它是程序开始执行的地方,也被称作程序入口点。main函数必须存在于Program部分的某个地方(个人观点,Program就是为了main函数而存在- -)。

 

 

以上是本人在学习Objective-C类时的一些心得体会,由于鄙人才疏学浅,如果有错误的地方还望看官多指教多批评。

EGORefreshTableHeaderView,列表视图下拉刷新开源类

关于如何在页面中使用EGORefreshTableHeaderView的文章网上一大把, 抄来抄去的, 但也都没什么大问题.  只是在XCode4.2的ARC环境中使用的时候, 错误一把. 借此机会, 完整的记录一下如何排除错误, 及使用的方法.

首先第一步当然是下载这个下拉更新的框架了.  https://github.com/enormego/EGOTableViewPullRefresh/downloads

 

下载之后解包, 然后将

EGORefreshTableHeaderDelegate.h

EGORefreshTableHeaderDelegate.m

这两个文件, 以及项目中的图片文件都复制到你的项目文件内, 这时候, 如果你启用了ARC, 应该会报一片错误, 让我们来具体看一下.

 

启用了ARC之后, 就不允许手动的release了, 因此, [view release], [lable release] 还有 autorelease这样的代码都需要删除掉.

在EGORefreshTableHeaderDelegate.m的这个文件中,   @synthesize delegate=_delegate;  会报错,  “Existing ivar “delegate” for assign property “delegate” must be… 

解决办法是需要将EGORefreshTableHeaderDelegate.h文件中的 assign 换为retain

 

  1. //@property(nonatomic,assign) id <EGORefreshTableHeaderDelegate> delegate;   //删除掉. 换为下面的
  2. @property(nonatomic,retain)id <EGORefreshTableHeaderDelegate> delegate;

 

这样代码就会通过编译了~ 这样就需要将EGORefreshTableHeaderView与我们的tableview整合了, 然后按照Demo的方法,

添加EGORefreshTableHeaderDelegate的接口,

定义_reloading, 和EGORefreshHeaderView

声明reloadTableViewDataSource和doneLoadingTableView这两个函数

 

 

  1. #import <UIKit/UIKit.h>
  2. #import “EGORefreshTableHeaderView.h”
  3. @interface FMFutureMessage : UIViewController<UITableViewDelegate, UITableViewDataSource,EGORefreshTableHeaderDelegate>
  4. {
  5.     BOOL _reloading;
  6.     EGORefreshTableHeaderView *_refreshHeaderView;
  7. }
  8. @property(strong, nonatomic) IBOutlet UITableView *tbView;
  9. -(void)reloadTableViewDataSource;
  10. -(void)doneLoadingTableViewData;
  11. @end

接下来, 我们需要将xib文件中的TableViewController与这里定义的tbView建立关联, 因为我忘记了指定tbView与XIB中的TabViewController, 导致了刷新箭头怎么样也显示不出来, 所以一定不要忘记啊~~~~
现在我们处理一下.m文件

 

处理m文件, 建立关联.和响应事件.

 

  1. – (void)viewDidLoad
  2. {
  3.     [super viewDidLoad];
  4.     // Do any additional setup after loading the view from its nib.
  5.     if(_refreshHeaderView == nil)
  6.     {
  7.         EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f – self.tbView.bounds.size.height, self.view.frame.size.width, self.tbView.bounds.size.height)];
  8.         view.delegate = self;
  9.         [self.tbView addSubview:view];
  10.         _refreshHeaderView = view;
  11.     }
  12.     [_refreshHeaderView refreshLastUpdatedDate];
  13. }

 

 

响应事件, 事件的响应代码就简单的多了, 按照DEMO的方法, 把接口的函数都声明了就OK了.

 

  1. -(void)reloadTableViewDataSource
  2. {
  3.     NSLog(@”==开始加载数据”);
  4.     [self.tbView reloadData];
  5.     _reloading = YES;
  6. }
  7. – (void)doneLoadingTableViewData{
  8.      NSLog(@”===加载完数据”);
  9.     //  model should call this when its done loading
  10.        _reloading = NO;
  11.     [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tbView];
  12. }
  13. #pragma mark –
  14. #pragma mark UIScrollViewDelegate Methods
  15. – (void)scrollViewDidScroll:(UIScrollView *)scrollView{
  16.     [_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
  17. }
  18. – (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
  19.     [_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
  20. }
  21. #pragma mark –
  22. #pragma mark EGORefreshTableHeaderDelegate Methods
  23. – (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
  24.     [self reloadTableViewDataSource];
  25.     [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
  26. }
  27. – (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
  28.     return _reloading; // should return if data source model is reloading
  29. }
  30. – (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
  31.     return [NSDate date]; // should return date data source was last changed
  32. }

最后, 如果是开发中文应用程序, 不要忘记进入EGORefreshTableHeaderView.m中, 将提示的英文换成中文.

12