iphone网络编程总结

一:确认网络环境3G/WIFI

1. 添加源文件和framework
    
    开发Web等网络应用程序的时候,需要确认网络环境,连接情况等信息。如果没有处理它们,是不会通过Apple的审(我们的)查的。
    Apple 的 例程 Reachability 中介绍了取得/检测网络状态的方法。要在应用程序程序中使用Reachability,首先要完成如下两部:
    
    1.1. 添加源文件:
    在你的程序中使用 Reachability 只须将该例程中的 Reachability.h 和 Reachability.m 拷贝到你的工程中。如下图:

1.2.添加framework:
    将SystemConfiguration.framework 添加进工程。如下图:
    
    
    2. 网络状态
    
    Reachability.h中定义了三种网络状态:
    typedef enum {
        NotReachable = 0,            //无连接
        ReachableViaWiFi,            //使用3G/GPRS网络
        ReachableViaWWAN            //使用WiFi网络
    } NetworkStatus;
    
    因此可以这样检查网络状态:

Reachability *r = [Reachability reachabilityWithHostName:@“www.apple.com”];
    switch ([r currentReachabilityStatus]) {
            case NotReachable:
                    // 没有网络连接
                    break;
            case ReachableViaWWAN:
                    // 使用3G网络
                    break;
            case ReachableViaWiFi:
                    // 使用WiFi网络
                    break;
    }
    
    3.检查当前网络环境
    程序启动时,如果想检测可用的网络环境,可以像这样
    // 是否wifi
    + (BOOL) IsEnableWIFI {
        return ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] != NotReachable);
    }

// 是否3G
    + (BOOL) IsEnable3G {
        return ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable);
    }
    例子:
    - (void)viewWillAppear:(BOOL)animated {    
    if (([Reachability reachabilityForInternetConnection].currentReachabilityStatus == NotReachable) &&
            ([Reachability reachabilityForLocalWiFi].currentReachabilityStatus == NotReachable)) {
            self.navigationItem.hidesBackButton = YES;
            [self.navigationItem setLeftBarButtonItem:nil animated:NO];
        }
    }

4. 链接状态的实时通知
    网络连接状态的实时检查,通知在网络应用中也是十分必要的。接续状态发生变化时,需要及时地通知用户:
    
    Reachability 1.5版本
    // My.AppDelegate.h
    #import "Reachability.h"

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
        NetworkStatus remoteHostStatus;
    }

@property NetworkStatus remoteHostStatus;

@end

// My.AppDelegate.m
    #import "MyAppDelegate.h"

@implementation MyAppDelegate
    @synthesize remoteHostStatus;

// 更新网络状态
    - (void)updateStatus {
        self.remoteHostStatus = [[Reachability sharedReachability] remoteHostStatus];
    }

// 通知网络状态
    - (void)reachabilityChanged:(NSNotification *)note {
        [self updateStatus];
        if (self.remoteHostStatus == NotReachable) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"AppName", nil)
                         message:NSLocalizedString (@"NotReachable", nil)
                        delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
            [alert show];
            [alert release];
        }
    }

// 程序启动器,启动网络监视
    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    
        // 设置网络检测的站点
        [[Reachability sharedReachability] setHostName:@"www.apple.com"];
        [[Reachability sharedReachability] setNetworkStatusNotificationsEnabled:YES];
        // 设置网络状态变化时的通知函数
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:)
                                                 name:@"kNetworkReachabilityChangedNotification" object:nil];
        [self updateStatus];
    }

- (void)dealloc {
        // 删除通知对象
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [window release];
        [super dealloc];
    }
    
    Reachability 2.0版本

// MyAppDelegate.h
    @class Reachability;

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
            Reachability  *hostReach;
        }

@end

// MyAppDelegate.m
    - (void)reachabilityChanged:(NSNotification *)note {
        Reachability* curReach = [note object];
        NSParameterAssert([curReach isKindOfClass: [Reachability class]]);
        NetworkStatus status = [curReach currentReachabilityStatus];
    
        if (status == NotReachable) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"AppName""
                              message:@"NotReachable"
                              delegate:nil
                              cancelButtonTitle:@"YES" otherButtonTitles:nil];
                              [alert show];
                              [alert release];
        }
    }
    - (void)applicationDidFinishLaunching:(UIApplication *)application {
        // ...
                  
        // 监测网络情况
        [[NSNotificationCenter defaultCenter] addObserver:self
                              selector:@selector(reachabilityChanged:)
                              name: kReachabilityChangedNotification
                              object: nil];
        hostReach = [[Reachability reachabilityWithHostName:@"www.google.com"] retain];
        hostReach startNotifer];
        // ...
    }

二:使用NSConnection下载数据
    
    1.创建NSConnection对象,设置委托对象
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self urlString]]];
    [NSURLConnection connectionWithRequest:request delegate:self];
    
    2. NSURLConnection delegate委托方法
        - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;  
        - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;  
        - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;  
        - (void)connectionDidFinishLoading:(NSURLConnection *)connection;

3. 实现委托方法
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        // store data
        [self.receivedData setLength:0];            //通常在这里先清空接受数据的缓存
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
           /* appends the new data to the received data */
        [self.receivedData appendData:data];        //可能多次收到数据,把新的数据添加在现有数据最后
    }

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        // 错误处理
    }

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        // disconnect
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;  
        NSString *returnString = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
        NSLog(returnString);
        [self urlLoaded:[self urlString] data:self.receivedData];
        firstTimeDownloaded = YES;
    }

三:使用NSXMLParser解析xml文件

1. 设置委托对象,开始解析
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];   //或者也可以使用initWithContentsOfURL直接下载文件,但是有一个原因不这么做:
    // It's also possible to have NSXMLParser download the data, by passing it a URL, but this is not desirable
    // because it gives less control over the network, particularly in responding to connection errors.
    [parser setDelegate:self];
    [parser parse];

2. 常用的委托方法
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
                                namespaceURI:(NSString *)namespaceURI
                                qualifiedName:(NSString *)qName
                                attributes:(NSDictionary *)attributeDict;
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
                                namespaceURI:(NSString *)namespaceURI
                                qualifiedName:(NSString *)qName;
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
    - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;

static NSString *feedURLString = @"http://www.yifeiyang.net/test/test.xml";

3.  应用举例
    - (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error
    {
        NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
        [parser setDelegate:self];
        [parser setShouldProcessNamespaces:NO];
        [parser setShouldReportNamespacePrefixes:NO];
        [parser setShouldResolveExternalEntities:NO];
        [parser parse];
        NSError *parseError = [parser parserError];
        if (parseError && error) {
            *error = parseError;
        }
        [parser release];
    }

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
                                        qualifiedName:(NSString*)qName attributes:(NSDictionary *)attributeDict{
        // 元素开始句柄
        if (qName) {
            elementName = qName;
        }
        if ([elementName isEqualToString:@"user"]) {
            // 输出属性值
            NSLog(@"Name is %@ , Age is %@", [attributeDict objectForKey:@"name"], [attributeDict objectForKey:@"age"]);
        }
    }

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
                                        qualifiedName:(NSString *)qName
    {
        // 元素终了句柄
        if (qName) {
               elementName = qName;
        }
    }

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
        // 取得元素的text
    }

NSError *parseError = nil;

一:确认网络环境3G/WIFI

1. 添加源文件和framework

开发Web等网络应用程序的时候,需要确认网络环境,连接情况等信息。如果没有处理它们,是不会通过Apple的审(我们的)查的。

Apple 的例程 Reachability 中介绍了取得/检测网络状态的方法。要在应用程序程序中使用Reachability,首先要完成如下两部:

1.1. 添加源文件:

在你的程序中使用 Reachability 只须将该例程中的 Reachability.h 和 Reachability.m 拷贝到你的工程中。如下图:

1.2.添加framework:

将SystemConfiguration.framework 添加进工程。如下图:

2. 网络状态

Reachability.h中定义了三种网络状态:

typedef enum {

NotReachable = 0,            //无连接

ReachableViaWiFi,            //使用3G/GPRS网络

ReachableViaWWAN            //使用WiFi网络

} NetworkStatus;

因此可以这样检查网络状态:

Reachability *r = [Reachability reachabilityWithHostName:@“www.apple.com”];

switch ([r currentReachabilityStatus]) {

case NotReachable:

// 没有网络连接

break;

case ReachableViaWWAN:

// 使用3G网络

break;

case ReachableViaWiFi:

// 使用WiFi网络

break;

}

3.检查当前网络环境

程序启动时,如果想检测可用的网络环境,可以像这样

// 是否wifi

+ (BOOL) IsEnableWIFI {

return ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] != NotReachable);

}

// 是否3G

+ (BOOL) IsEnable3G {

return ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable);

}

例子:

- (void)viewWillAppear:(BOOL)animated {

if (([Reachability reachabilityForInternetConnection].currentReachabilityStatus == NotReachable) &&

([Reachability reachabilityForLocalWiFi].currentReachabilityStatus == NotReachable)) {

self.navigationItem.hidesBackButton = YES;

[self.navigationItem setLeftBarButtonItem:nil animated:NO];

}

}

4. 链接状态的实时通知

网络连接状态的实时检查,通知在网络应用中也是十分必要的。接续状态发生变化时,需要及时地通知用户:

Reachability 1.5版本

// My.AppDelegate.h

#import "Reachability.h"

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {

NetworkStatus remoteHostStatus;

}

@property NetworkStatus remoteHostStatus;

@end

// My.AppDelegate.m

#import "MyAppDelegate.h"

@implementation MyAppDelegate

@synthesize remoteHostStatus;

// 更新网络状态

- (void)updateStatus {

self.remoteHostStatus = [[Reachability sharedReachability] remoteHostStatus];

}

// 通知网络状态

- (void)reachabilityChanged:(NSNotification *)note {

[self updateStatus];

if (self.remoteHostStatus == NotReachable) {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"AppName", nil)

message:NSLocalizedString (@"NotReachable", nil)

delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];

[alert show];

[alert release];

}

}

// 程序启动器,启动网络监视

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// 设置网络检测的站点

[[Reachability sharedReachability] setHostName:@"www.apple.com"];

[[Reachability sharedReachability] setNetworkStatusNotificationsEnabled:YES];

// 设置网络状态变化时的通知函数

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:)

name:@"kNetworkReachabilityChangedNotification" object:nil];

[self updateStatus];

}

- (void)dealloc {

// 删除通知对象

[[NSNotificationCenter defaultCenter] removeObserver:self];

[window release];

[super dealloc];

}

Reachability 2.0版本

// MyAppDelegate.h

@class Reachability;

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {

Reachability  *hostReach;

}

@end

// MyAppDelegate.m

- (void)reachabilityChanged:(NSNotification *)note {

Reachability* curReach = [note object];

NSParameterAssert([curReach isKindOfClass: [Reachability class]]);

NetworkStatus status = [curReach currentReachabilityStatus];

if (status == NotReachable) {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"AppName""

message:@"NotReachable"

delegate:nil

cancelButtonTitle:@"YES" otherButtonTitles:nil];

[alert show];

[alert release];

}

}

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// ...

// 监测网络情况

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(reachabilityChanged:)

name: kReachabilityChangedNotification

object: nil];

hostReach = [[Reachability reachabilityWithHostName:@"www.google.com"] retain];

hostReach startNotifer];

// ...

}

二:使用NSConnection下载数据

1.创建NSConnection对象,设置委托对象

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self urlString]]];

[NSURLConnection connectionWithRequest:request delegate:self];

2. NSURLConnection delegate委托方法

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

- (void)connectionDidFinishLoading:(NSURLConnection *)connection;

3. 实现委托方法

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

// store data

[self.receivedData setLength:0];            //通常在这里先清空接受数据的缓存

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

/* appends the new data to the received data */

[self.receivedData appendData:data];        //可能多次收到数据,把新的数据添加在现有数据最后

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

// 错误处理

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

// disconnect

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

NSString *returnString = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];

NSLog(returnString);

[self urlLoaded:[self urlString] data:self.receivedData];

firstTimeDownloaded = YES;

}

三:使用NSXMLParser解析xml文件

1. 设置委托对象,开始解析

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];   //或者也可以使用initWithContentsOfURL直接下载文件,但是有一个原因不这么做:

// It's also possible to have NSXMLParser download the data, by passing it a URL, but this is not desirable

// because it gives less control over the network, particularly in responding to connection errors.

[parser setDelegate:self];

[parser parse];

2. 常用的委托方法

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName

namespaceURI:(NSString *)namespaceURI

qualifiedName:(NSString *)qName

attributes:(NSDictionary *)attributeDict;

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName

namespaceURI:(NSString *)namespaceURI

qualifiedName:(NSString *)qName;

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;

static NSString *feedURLString = @"http://www.yifeiyang.net/test/test.xml";

3.  应用举例

- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error

{

NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];

[parser setDelegate:self];

[parser setShouldProcessNamespaces:NO];

[parser setShouldReportNamespacePrefixes:NO];

[parser setShouldResolveExternalEntities:NO];

[parser parse];

NSError *parseError = [parser parserError];

if (parseError && error) {

*error = parseError;

}

[parser release];

}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI

qualifiedName:(NSString*)qName attributes:(NSDictionary *)attributeDict{

// 元素开始句柄

if (qName) {

elementName = qName;

}

if ([elementName isEqualToString:@"user"]) {

// 输出属性值

NSLog(@"Name is %@ , Age is %@", [attributeDict objectForKey:@"name"], [attributeDict objectForKey:@"age"]);

}

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI

qualifiedName:(NSString *)qName

{

// 元素终了句柄

if (qName) {

elementName = qName;

}

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

{

// 取得元素的text

}

NSError *parseError = nil;

iOS-iphone网络编程总结的更多相关文章

  1. 聊聊iOS中网络编程长连接的那些事

    1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...

  2. IOS开发——网络编程总汇

    关于IOS的网络编程,大家都会想到C实现的底层BSD ,CFNetwork和NSURL之类的库,虽然如今非常多第三方库非常方便,可是作为一名开发人员,也须要了解底层代码. 以下的思维导图是关于眼下开发 ...

  3. 【iOS】网络编程:上传图片到服务器

    在网络编程中,如果需要上传图片,那么他的方法将会和普通的上传数据不同,下面将讲解如何上传图片. 环境信息: Mac OS X 10.9.5 Xcode 5.1.1 IOS 7.1 正文: - (NSU ...

  4. ios开发 网络编程浅析(一)

    iphone包含了很多框架和库,从底层的套接字到不同层次的封装,可以方便地给程序添加网络功能. (1)BSD套接字.最底层的套接字,这是Unix网络开发常用的API.如果从其他系统移植程序,而程序用的 ...

  5. iOS:网络编程中三个数据解析协议HTTP、XML、JSON的详细介绍

    网络编程:HTTP协议.XML数据协议.JSON数据协议: HTTP: 1.HTTP传输数据有四种方式:Get方式.Post方式.同步请求方式.异步请求方式. 说明:同步和异步请求方式在创建链接对象和 ...

  6. iOS开发——网络编程Swift篇&Alamofire详解

    Alamofire详解 预览图 Swift Alamofire 简介 Alamofire是 Swift 语言的 HTTP 网络开发工具包,相当于Swift实现AFNetworking版本. 当然,AF ...

  7. iOS开发——网络编程Swift篇&(八)SwiftyJSON详解

    SwiftyJSON详解 最近看了一些网络请求的例子,发现Swift在解析JSON数据时特别别扭,总是要写一大堆的downcast(as?)和可选(Optional),看?号都看花了.随后发现了这个库 ...

  8. iOS开发——网络编程OC篇&(一)XMPP简单介绍与准备

    XMPP简单介绍与准备 一.即时通讯简单介绍 1.简单说明 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈 ...

  9. iOS开发——网络编程OC篇&Socket编程

    Socket编程 一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作 ...

  10. iOS开发——网络编程OC篇&使用WebView构建HyBird应用

    使用WebView构建HyBird应用 HyBird是一种本地技术与Web相结合,能过实现跨平台的移动应用开发,最常用的一个框架:PhoneGap 一:首先,写好html代码 <!DOCTYPE ...

随机推荐

  1. 关于创建Django表单Forms继承BaseForm的问题

    在创建Django表单时,因为需要验证用户输入的验证码是否正确,因此需要在session里提取当前验证码的值和POST提交过来的值进行比对,如图: form.py from django import ...

  2. Vue 获取dom元素中的自定义属性值

    方法一: HTML <div id="app"> <button @click="getData($event,'100')">点我&l ...

  3. 学到了林海峰,武沛齐讲的Day30 完 TCP UDP

    TCP UDP 其中讲了数据的传输.各有利弊 个人理解 就是这样将高并发,低数据,高数据的传输,稳定高效

  4. How to Fix Broken Packages in Ubuntu

    How to Fix Broken Packages in Ubuntu By Nick Congleton – Posted on Jan 11, 2019 in Linux   Apt, Ubun ...

  5. Laravel Repository Pattern

    Laravel Repository Pattern   The Repository Pattern can be very helpful to you in order to keep your ...

  6. Bootstap学习的实用网站

    基本CSS样式 http://v2.bootcss.com/base-css.html 93 Twitter Bootstrap HTML Templates https://shapebootstr ...

  7. TCP数据报结构以及三次握手

    TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的.可靠的.基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接. 客户端在收发数据前要 ...

  8. manjaro xfce4 使用super+D快捷键显示桌面(以及使用super+方向键调整窗口)设置无效

    xfce4 有两个地方设置快捷键:Keyboard -> application shortcuts 和 window manager -> keyboard. window manage ...

  9. base/7/x86_64/filelists_db FAILED

      解决办法: [root@localhost ~]# cd /var/lib/rpm [root@localhost rpm]# rm -rf __db.* # 清除原 rpmdb 文件 [root ...

  10. [bzoj 2768]&[bzoj 1877]

    传送门1 传送门1 Solution 两道比较裸的题... 复习一下最大流和费用流的模板. Code[bzoj 2768][JLOI 2010] 冠军调查 #include<bits/stdc+ ...