SlideShare a Scribd company logo
1 of 67
Class 13
iOS 應⽤用軟體設計
課程⼤大綱
•   擷取網路資料
    •   QV128:擷取網路上的 plist

•   NSURLConnection
    •   QV129:載⼊入網路的⼤大圖檔,並能夠顯⽰示下載進度

    •   QV130:使⽤用 post 傳遞

•   NSXMLParser
    •   QV135:RSS 讀取網路資料

    •   Samples:SeismicXML, LazyTableImages

•   URL Scheme
    •   QV121:呼叫系統內建的 App

    •   QV122:⾃自訂 URL Scheme

    •   QV123 + QV124 :openURL 功能測試『qrapp://』
    •   Samples:LaunchMe
擷取網路資料

• initWithContentsOfURL:
  ⼀一種⽅方法,屬於 NSString, NSArray,
  NSDictionary, ... 的⽅方法,直接將資料轉成
  特定的資料型態

• NSURLConnection class
  ⼀一個類別,進⾏行 http 資料傳送 (get, post)
物件擷取網路資料的⽅方法
•   NSString, NSMutableString
    + stringWithContentsOfURL: encoding: error:
    - initWithContentsOfURL: encoding: error:
•   NSArray, NSMutableArray
    + arrayWithContentsOfURL:
    - initWithContentsOfURL:
•   NSDictionary, NSMutableDictionary
    + dictionaryWithContentsOfURL:
    - initWithContentsOfURL:
•   NSData, NSMutableData
    + dataWithContentsOfURL:
    + dataWithContentsOfURL: options: error:
    - initWithContentsOfURL:
    - initWithContentsOfURL: options: error:
Project QV128

 讀取網路上的 plist 檔
 ⽅方法⼀一:直接讀取
 ⽅方法⼆二:加⼊入訊息通知
 以進⾏行背景處理
ViewController.h


@interface ViewController : UIViewController
{
    NSDictionary *dataDict;
    IBOutlet UILabel *display;
}

- (IBAction) btnStart:(id)sender;
- (IBAction) btnStart2:(id)sender;

- (void) loadFile;
- (void) didDownloadDictionary: (NSNotification *)info;

@end
ViewController.m (1/3)
      ⽅方法⼀一:直接讀取網路資料
               (同步⽅方式)


- (IBAction) btnStart:(id)sender
{
    display.text = @"......";

    NSURL *url = [NSURL URLWithString:DictionaryURL];
    dataDict = [[NSDictionary alloc] initWithContentsOfURL:url];

    display.text = [dataDict description];
}




               注意:等資料下載完畢後才會顯⽰示
ViewController.m (2/3)
       ⽅方法⼆二:建⽴立訊息通知


- (IBAction) btnStart2:(id)sender
{
    display.text = @"......";

    // 產⽣生通知的物件
    [[NSNotificationCenter defaultCenter] addObserver:self
       selector:@selector(didDownloadDictionary:)
           name:DidDownloadedNotification object:nil];

    // 呼叫
    [self performSelectorInBackground:@selector(loadFile) withObject:nil];

    display.text = @"downloading......";
}


                                能在要求下載後繼續進⾏行程序
ViewController.m (3/3)


- (void) loadFile
{
    NSURL *url = [NSURL URLWithString:DictionaryURL];
    dataDict = [NSDictionary dictionaryWithContentsOfURL:url];

    [[NSNotificationCenter defaultCenter]
         postNotificationName:DidDownloadedNotification
         object:self userInfo:dataDict];
}


- (void) didDownloadDictionary: (NSNotification *)info
{
    // 接收結果
    dataDict = [info userInfo];
    display.text = [dataDict description];
}


                                      下載完畢後通知執⾏行
NSURLConnection
NSURLConnection class
同步化 request

// 初始化請求
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

// 設置URL
[request setURL:[NSURL URLWithString:urlStr]];

// 設置HTTP⽅方法 (GET 或 POST)
[request setHTTPMethod:@"GET"];

// 發送同步請求, 這裡的returnData就是傳回的資料內容
NSData *returnData = [NSURLConnection sendSynchronousRequest:request
                                returningResponse:nil error:nil];
⾮非同步化 request
NSMutableData*	
  buf	
  =	
  [[NSMutableData	
  alloc]	
  initWithLength:0];
NSURLConnection*	
  connection	
  =	
  [[NSURLConnection	
  alloc]	
  initWithRequest:req	
  
delegate:self];
	
  
//	
  連線建⽴立成功收到回應時,	
  會觸發
-­‐	
  (void)connection:(NSURLConnection	
  *)connection	
  didReceiveResponse:
(NSURLResponse	
  *)	
  aResponse;
	
  
//	
  每收到⼀一次網路封包資料,會觸發
-­‐	
  (void)connection:(NSURLConnection	
  *)connection	
  didReceiveData:(NSData	
  *)data
{
	
  	
  	
  	
  [buf	
  appendData:data];
}
	
  
//	
  網路錯誤時觸發
-­‐	
  (void)connection:(NSURLConnection	
  *)connection	
  didFailWithError:(NSError	
  
*)error;
	
  
//	
  全部資料接收完畢時觸發
-­‐	
  (void)connectionDidFinishLoading:(NSURLConnection	
  *)connection;
Project QV129

 載⼊入網路的⼤大圖檔,並能
 夠顯⽰示下載進度
 利⽤用 NSURLConnection
 讀取網路資料
 UIProgressView 進度顯⽰示
ViewController.h




#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    NSURLConnection *connect;

    IBOutlet UIImageView *img;
    IBOutlet UIProgressView *downloadProgress;

    NSMutableData *tempData;   //下載時暫存⽤用的記憶體
    long expectedLength;       //檔案⼤大⼩小
}

@end
ViewController.m (1/4)
           建⽴立連線讀取網路資料


- (void)viewDidLoad
{
    downloadProgress.progress = 0.0;

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:
       [NSURL URLWithString:@"http://web.trtc.com.tw/img/ALL/Route2200/051.jpg"]];

    [request setHTTPMethod:@"GET"];
    [request setValue:@"application/x-www-form-urlencoded"
             forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"Mobile Safari 1.1.3 (iPhone; U; CPU like Mac OS X; en)"
             forHTTPHeaderField:@"User-Agent"];

    tempData = [NSMutableData alloc];
    connect = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [super viewDidLoad];
}
ViewController.m (2/4)
    錯誤處理

- (void)connection:(NSURLConnection *)connection didFailWithError:
(NSError *)error
{
    //發⽣生錯誤
! NSLog(@"發⽣生錯誤");
}



連線建⽴立成功處理

- (void)connection: (NSURLConnection *)connection didReceiveResponse:
(NSURLResponse *)aResponse
{
    //連線建⽴立成功,取得狀態
    NSInteger status = (NSInteger)[(NSHTTPURLResponse *)aResponse
statusCode];
    NSLog(@"%d", status);

     expectedLength = [aResponse expectedContentLength]; //儲存檔案⻑⾧長度
}
ViewController.m (3/4)
    封包接收



-(void) connection:(NSURLConnection *)connection didReceiveData:
(NSData *) incomingData
{
    //收到封包,將收到的資料塞進緩衝中並修改進度條
! [tempData appendData:incomingData];

    double ex = expectedLength;
    downloadProgress.progress = [tempData length] / ex;
}
ViewController.m (4/4)
    檔案下載完成處理


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //檔案下載完成
    //取得可讀寫的路徑
    NSArray *pathList =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
! NSString *path = [pathList objectAtIndex:0];

    //加上檔名
    path = [path stringByAppendingPathComponent: @"00.jpg"];
    NSLog(@"儲存路徑:%@", path);
!
!   //寫⼊入檔案
    [tempData writeToFile:path atomically:NO];
    tempData = nil;

    img.image = [UIImage imageWithContentsOfFile:path]; //顯⽰示圖⽚片在畫⾯面中
}
Project QV130


 利⽤用 NSURLConnection
 的 post ⽅方法傳遞資料
 WebView 顯⽰示取得的內容
測試網⾴頁
http://web.trtc.com.tw/c/TicketALLresult.asp
ViewController.h



#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    NSURLConnection *connect;

    IBOutlet UIWebView *webView;
    IBOutlet UIProgressView *downloadProgress;

    NSMutableData *tempData;   //下載時暫存⽤用的記憶體
    long expectedLength;       //檔案⼤大⼩小
}

@end
建⽴立連線 (post) ⽅方法                          ViewController.m (1/3)

- (void)viewDidLoad
{
    downloadProgress.progress = 0.0;

    NSString *post = @"submit=a &select2=030";
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding
                             allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
!
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL
             URLWithString:@"http://web.trtc.com.tw/c/TicketALLresult.asp"]];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/x-www-form-urlencoded"
             forHTTPHeaderField:@"Content-Type"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"Mobile Safari 1.1.3 (iPhone; U; CPU like Mac OS X; en)"
             forHTTPHeaderField:@"User-Agent"];
!
    [request setHTTPBody:postData]; // 加上 post 的資料
!
    tempData = [NSMutableData alloc];
    connect = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [super viewDidLoad];
}
ViewController.m (2/3)
錯誤處理 連線建⽴立成功處理 封包接收

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    // 發⽣生錯誤
! NSLog(@"發⽣生錯誤");
}

- (void)connection: (NSURLConnection *)connection didReceiveResponse:
(NSURLResponse *)aResponse
{
    // 連線建⽴立成功
    // 取得狀態
    NSInteger status = (NSInteger)[(NSHTTPURLResponse *)aResponse statusCode];
    NSLog(@"%d", status);

    expectedLength = [aResponse expectedContentLength]; //儲存檔案⻑⾧長度
}

-(void) connection:(NSURLConnection *)connection didReceiveData: (NSData *)
incomingData
{
    // 收到封包,將收到的資料塞進緩衝中並修改進度條
! [tempData appendData:incomingData];

    double ex = expectedLength;
    downloadProgress.progress = [tempData length] / ex;
}
ViewController.m (3/3)
    檔案下載完成處理



- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // 內容取得完成
    NSString *loadData = [[NSMutableString alloc]
             initWithData:tempData encoding:NSUTF8StringEncoding];

    [webView loadHTMLString:loadData baseURL:nil];
    NSLog(@"%@", loadData);

    tempData = nil;
}
NSXMLParser class
Event-Driven XML Parsing
NSXMLParserDelegate
    protocol
Project QV135

 RSS 讀取網路資料
 讀取 RSS 網址,以 XML ⽅方
 式剖析 (針對 rss 格式)
 使⽤用 TableView 顯⽰示資料
RSS 之內容範例




  需要解析的格式

<item>
   <title></title>
   <link></link>
   <description></description>
</item>
將 rss 之解析
寫成⼀一個類別
NSXMLParser 的代理⽅方法
            parser:(NSXMLParser *)parser
檢測到tag的開始   didStartElement:(NSString *)elementName
            namespaceURI:(NSString *)namespaceURI
            qualifiedName:(NSString *)qName
            attributes:(NSDictionary *)attributeDict




            parser:(NSXMLParser *)parser
檢測到內部的資料    foundCharacters:(NSString *)string




            parser:(NSXMLParser *)parser
            didEndElement:(NSString *)elementName
檢測到tag的結尾   namespaceURI:(NSString *)namespaceURI
            qualifiedName:(NSString *)qName
RSSParser 類別
將 rss ⽂文件轉換為⼀一個陣列

主程式     RSSParser 類別
         NSMutableArray   didStartElement:
            *result;

              title
                          foundCharacters:
              link
           description
              title
              link        didEndElement:
           description
              title
              link
           description
#import <Foundation/Foundation.h>
                                                   RSSParser.h
//   ⽤用來定義標籤的⾃自定義變數
//   tagTitle = <title>
//   tagLink = <link>
//   tagDescription = <description>
//   tagunknown = 未知,不處理項⺫⽬目

typedef enum { tagTitle, tagLink, tagDescription, tagUnknown } RSSTag;

@interface RSSParser : NSObject <NSXMLParserDelegate>
{
    NSMutableDictionary *item; // 存放每筆news資料
    RSSTag currentTag; // ⺫⽬目前正在解析的標籤
    BOOL startItem; // 是否開始解析
}

// 解析後所有的news
@property (nonatomic, retain) NSMutableArray *result;

- (id) initWithData:(NSData *) data;
                                            解析內容後,將⽂文章條⺫⽬目
@end
                                            (含title, description, link)
                                                    以陣列儲存
// 找到某個標籤的開始
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:
(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"item"])
    {
        startItem = YES;
                                                             RSSParser.m (1/3)
        item = [NSMutableDictionary new];
    }

    // 發現 item 後才開始解析
    if(startItem)
    {
        if([elementName isEqualToString:@"title"])
        {
            currentTag = tagTitle;
        }
        else if([elementName isEqualToString:@"description"])
        {
            currentTag = tagDescription;
        }
        else if([elementName isEqualToString:@"link"])     (1) 當標籤開始時,分
        {
            currentTag = tagLink;                           別對內容為第⼀一層的
        }
        else                                               <item>,或是 <title>,
        {
            currentTag = tagUnknown;                       <description>, <link>
        }
    }
                                                                 進⾏行處理
}
// XML 的內⽂文
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    // 將空⽩白及換列符號去除
    NSString *value = [string stringByTrimmingCharactersInSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet]];

    // 若沒有任何內容或標籤未知則不處理
    if([value length]==0 || currentTag==tagUnknown)          RSSParser.m (2/3)
    {
        return;
    }

    // ⽐比對正在解析的標籤,並儲存該標籤內的⽂文字於 item 內
    switch (currentTag)
    {
        case tagTitle:
            [item setValue:value forKey:@"title"];
            break;

        case tagDescription:
            [item setValue:value forKey:@"description"];
            break;
                                                            (2) 處理標籤的內容:
        case tagLink:
            [item setValue:value forKey:@"link"];          若之前的標籤是 <title>,
            break;
                                                           <description>, <link> 之
        default:
            break;                                           ⼀一 ,則存⼊入陣列內
    }
}
RSSParser.m (3/3)



// 找到某個標籤的結尾
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:@"item"])
    {
        NSDictionary *parsedItem = [[NSDictionary alloc] initWithDictionary:item];
        [self.result addObject:parsedItem];
        item = nil;
        startItem = NO;
    }
}




                                                     (3) 讀取到標籤的結尾時,
                                                       便可將單筆項⺫⽬目記錄於
                                                          NSDictionary 內
MasterViewController.h
         主程式部分


#import <UIKit/UIKit.h>

#import "RSSParser.h"

@class DetailViewController;

@interface MasterViewController : UITableViewController
{
    NSArray *result;
}

@property (strong, nonatomic) DetailViewController *detailViewController;

@end
MasterViewController.m (1/2)


- (void)viewDidLoad
{
    [super viewDidLoad];

    // 抓取資料
    NSURL *url = [[NSURL alloc]
                 initWithString:@"http://udn.com/udnrss/udpopular.xml"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSData *data = [NSURLConnection sendSynchronousRequest:request
                                    returningResponse:nil error:nil];

    RSSParser *parser = [[RSSParser alloc] initWithData:data];
    result = [[NSArray alloc] initWithArray:parser.result];
    parser = nil;

    ****** 省略部分程式 ******
}                                                    以同步⽅方式取得
                                                      全部原始資料
MasterViewController.m (2/2)

#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
    // return _objects.count;
    return [result count];                  資料已存在物件內,直接取⽤用
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
    ****** 省略部分程式 ******

    //NSDate *object = [_objects objectAtIndex:indexPath.row];
    //cell.textLabel.text = [object description];

    NSDictionary *item = [result objectAtIndex:indexPath.row];
    cell.textLabel.text = [item objectForKey:@"title"];

    return cell;
}
範例觀摩:SeismicXML

      The SeismicXML sample application
      demonstrates how to use NSXMLParser to
      parse XML data. When you launch the
      application it downloads and parses an
      RSS feed from the United States
      Geological Survey (USGS) that provides
      data on recent earthquakes around the
      world. It displays the location, date, and
      magnitude of each earthquake, along with
      a color-coded graphic that indicates the
      severity of the earthquake. The XML
      parsing occurs on a background thread
      using NSOperation and updates the
      earthquakes table view with batches of
      parsed objects.
範例觀摩:LazyTableImages


This sample demonstrates a multi-stage
approach to loading and displaying a
UITableView. It begins by loading the relevant
text from an RSS feed so the table can load
as quickly as possible, and then downloads
the images for each row asynchronously so
the UI is more responsive
iOS 上使⽤用 JSON 參考資料


•   Getting Started with JSON in iOS5
    http://blogs.captechconsulting.com/blog/nathan-jones/getting-started-json-ios5/


•   JavaScript Object Notation Serialization
    http://pragprog.com/magazines/2011-11/inside-ios-/


•   不要使⽤用 SBJSON (json-framework)
    http://blog.devtang.com/blog/2012/05/05/do-not-use-sbjson/
URL Scheme
URL Scheme

• 以 openURL: 的⽅方法開啟外部的應⽤用程式
• 認識內建 App 的 URL Scheme
• ⾃自建 URL Scheme
範例:URL Scheme

• QV121:呼叫系統內建的 App
• QV122:⾃自訂 URL Scheme
• QV123:openURL 功能測試之呼叫程式
• QV124:openURL 功能測試之被呼叫程
 式『qrapp://』
Project QV121


 URL Scheme
 開啟 Safari、電話、簡訊、
 Mail、iBooks 等
ViewController.h



#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

- (IBAction) openSafari:(id)sender;

- (IBAction) openGoogleMap1:(id)sender;
- (IBAction) openGoogleMap2:(id)sender;

- (IBAction) openPhone:(id)sender;
- (IBAction) openSMS:(id)sender;

- (IBAction) openMail:(id)sender;
- (IBAction) openMailGood:(id)sender;

- (IBAction) openIBooks:(id)sender;

@end
ViewController.m (1/5)




- (IBAction) openSafari:(id)sender
{
    NSString *stringURL = @"http://www.apple.com.tw/";

    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
ViewController.m (2/5)
- (IBAction) openGoogleMap1:(id)sender
{
    NSString *stringURL = @"http://maps.google.com/maps?q=Taiwan";
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}

                                                                網址
- (IBAction) openGoogleMap2:(id)sender
{
    NSString *title = @"台北101";
    NSDecimalNumber *latitude = [NSDecimalNumber
decimalNumberWithString:@"25.033671"]; // 緯度
    NSDecimalNumber *longitude = [NSDecimalNumber
decimalNumberWithString:@"121.564427"]; // 經度
    NSInteger zoomValue = 12;

    NSString *stringURL = [NSString stringWithFormat:@"http://
maps.google.com/maps?q=%@@%1.6f,%1.6f&z=%d", [title
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [latitude
floatValue], [longitude floatValue], zoomValue];

    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
ViewController.m (3/5)




- (IBAction) openPhone:(id)sender
{
    NSString *stringURL = @"tel:+8860212345678";         電話
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}


- (IBAction) openSMS:(id)sender
{
    NSString *stringURL = @"sms:+12345678901";           簡訊
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
ViewController.m (4/5)
- (IBAction) openMail:(id)sender
{
    NSString *stringURL = @"mailto:happy@mail.com";          郵件
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}


- (IBAction) openMailGood:(id)sender
{
    // 預先填⼊入內⽂文
    NSString *subject = @"標題";
    NSString *msgBody = @"信件內⽂文";
    NSString *emailAddress = @"hello@mail.com";
    NSString *ccAddr = @"world@mail.com";
    NSString *bccAddr = @"good@mail.com";

    NSString *stringURL = [NSString stringWithFormat:@"mailto:%@?cc=
%@&bcc=%@&subject=%@&body=%@", emailAddress, ccAddr, bccAddr,
subject, msgBody];

    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
ViewController.m (5/5)




- (IBAction) openIBooks:(id)sender
{
    NSString *stringURL = @"itms-books://";
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
⾃自我練習

測試呼叫 Youtube 影⽚片
測試呼叫某個 AppStore 內的 app


問題:兩個應⽤用程式使⽤用相同的 URL
Scheme 時會如何?
Project QV122


 ⾃自訂 URL Scheme
 同時包含測試程式及被呼叫
 程式
(1) 選擇專案設定




                      (2) 新增 URL Type




(3) 設定 URL Schemes
@interface AppDelegate : UIResponder <UIApplicationDelegate,
UIAlertViewDelegate>
{
    UIAlertView *usageAlertView;
}
                                                  AppDelegate.h
@end


             先做⼀一個彈出視窗
                  (解說⽤用)                          AppDelegate.h


- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSString *message =
          @"請按『Go』開啟Safari,並在Safari輸⼊入⼀一個開頭為 testurl:// 的 URL";
    usageAlertView = [[UIAlertView alloc] initWithTitle:@"Usage"
            message:message delegate:self cancelButtonTitle:@"Go"
            otherButtonTitles:nil];
    [usageAlertView show];
     return YES;
}
AppDelegate.m (1/2)

       再開出 Safari 應⽤用程式
               (解說⽤用)

- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:
(NSInteger)buttonIndex
{
    if(buttonIndex != -1)
    {
        [[UIApplication sharedApplication]
               openURL:[NSURL URLWithString:@"http://www.apple.com"]];
    }
}
系統呼叫執⾏行後                                   AppDelegate.m (2/2)
       處理傳⼊入的訊息

- (BOOL) application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{

    if (!url) return NO;

    NSString *URLString = [url absoluteString];
    if (!URLString) return NO;

   NSString *message = [NSString stringWithFormat:@"收到訊息: %@n誰呼叫
我: %@", URLString, sourceApplication];

    UIAlertView *openAlert = [[UIAlertView alloc] initWithTitle:@"啟動訊
息" message:message delegate:nil cancelButtonTitle:@"OK"
otherButtonTitles:nil];

    [openAlert show];

    return YES;
}
在此輸⼊入 testurl://Hello
Project QV123


 QV123+QV124 搭配測試
 ⾃自訂 URL Scheme
 此為呼叫程式
ViewController.xib




                                         指定呼叫的
ViewController.m                        URL Scheme


             - (IBAction) openMyApp:(id)sender
             {
                 NSString *stringURL = @"qrapp://HelloWorld";
                 NSURL *url = [NSURL URLWithString:stringURL];
                 [[UIApplication sharedApplication] openURL:url];
             }
Project QV124


 QV123+QV124 搭配測試
 ⾃自訂 URL Scheme
 此為被呼叫後執⾏行的程式
指定此應⽤用程式的
 URL Scheme
AppDelegate.m


- (BOOL) application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:
(id)annotation
{
    if (!url) return NO;

    NSString *URLString = [url absoluteString];
    if (!URLString) return NO;

    NSString *message = [NSString stringWithFormat:@"收到訊息: %@n誰呼叫
我: %@", URLString, sourceApplication];
    UIAlertView *openAlert = [[UIAlertView alloc] initWithTitle:@"啟動訊
息" message:message delegate:nil cancelButtonTitle:@"OK"
otherButtonTitles:nil];
    [openAlert show];

    return YES;
}
範例觀摩:LaunchMe
............

More Related Content

What's hot

REST/JSON/CoreData Example Code - A Tour
REST/JSON/CoreData Example Code - A TourREST/JSON/CoreData Example Code - A Tour
REST/JSON/CoreData Example Code - A TourCarl Brown
 
eZ Publish cluster unleashed revisited
eZ Publish cluster unleashed revisitedeZ Publish cluster unleashed revisited
eZ Publish cluster unleashed revisitedBertrand Dunogier
 
Asynchronicity: concurrency. A tale of
Asynchronicity: concurrency. A tale ofAsynchronicity: concurrency. A tale of
Asynchronicity: concurrency. A tale ofJoel Lord
 
Large Scale Crawling with Apache Nutch and Friends
Large Scale Crawling with Apache Nutch and FriendsLarge Scale Crawling with Apache Nutch and Friends
Large Scale Crawling with Apache Nutch and Friendslucenerevolution
 
Webinar: MongoDB Persistence with Java and Morphia
Webinar: MongoDB Persistence with Java and MorphiaWebinar: MongoDB Persistence with Java and Morphia
Webinar: MongoDB Persistence with Java and MorphiaMongoDB
 
Asynchonicity: concurrency. A tale of
Asynchonicity: concurrency. A tale ofAsynchonicity: concurrency. A tale of
Asynchonicity: concurrency. A tale ofJoel Lord
 
Cassandra summit 2013 - DataStax Java Driver Unleashed!
Cassandra summit 2013 - DataStax Java Driver Unleashed!Cassandra summit 2013 - DataStax Java Driver Unleashed!
Cassandra summit 2013 - DataStax Java Driver Unleashed!Michaël Figuière
 
TDC2016SP - Trilha DevOps Java
TDC2016SP - Trilha DevOps JavaTDC2016SP - Trilha DevOps Java
TDC2016SP - Trilha DevOps Javatdc-globalcode
 
Exploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osqueryExploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osqueryZachary Wasserman
 
ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)YoungHeon (Roy) Kim
 
Entity Framework Core & Micro-Orms with Asp.Net Core
Entity Framework Core & Micro-Orms with Asp.Net CoreEntity Framework Core & Micro-Orms with Asp.Net Core
Entity Framework Core & Micro-Orms with Asp.Net CoreStephane Belkheraz
 
Introduce leo-redundant-manager
Introduce leo-redundant-managerIntroduce leo-redundant-manager
Introduce leo-redundant-managerParas Patel
 
Building .NET Apps using Couchbase Lite
Building .NET Apps using Couchbase LiteBuilding .NET Apps using Couchbase Lite
Building .NET Apps using Couchbase Litegramana
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinLorenz Cuno Klopfenstein
 
Hidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-PersistenceHidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-PersistenceSven Ruppert
 
Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v
Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v
Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v Arian Gutierrez
 

What's hot (19)

REST/JSON/CoreData Example Code - A Tour
REST/JSON/CoreData Example Code - A TourREST/JSON/CoreData Example Code - A Tour
REST/JSON/CoreData Example Code - A Tour
 
Gl qtp day 3 2
Gl qtp day 3   2Gl qtp day 3   2
Gl qtp day 3 2
 
eZ Publish cluster unleashed revisited
eZ Publish cluster unleashed revisitedeZ Publish cluster unleashed revisited
eZ Publish cluster unleashed revisited
 
Asynchronicity: concurrency. A tale of
Asynchronicity: concurrency. A tale ofAsynchronicity: concurrency. A tale of
Asynchronicity: concurrency. A tale of
 
Large Scale Crawling with Apache Nutch and Friends
Large Scale Crawling with Apache Nutch and FriendsLarge Scale Crawling with Apache Nutch and Friends
Large Scale Crawling with Apache Nutch and Friends
 
Webinar: MongoDB Persistence with Java and Morphia
Webinar: MongoDB Persistence with Java and MorphiaWebinar: MongoDB Persistence with Java and Morphia
Webinar: MongoDB Persistence with Java and Morphia
 
Asynchonicity: concurrency. A tale of
Asynchonicity: concurrency. A tale ofAsynchonicity: concurrency. A tale of
Asynchonicity: concurrency. A tale of
 
Cassandra summit 2013 - DataStax Java Driver Unleashed!
Cassandra summit 2013 - DataStax Java Driver Unleashed!Cassandra summit 2013 - DataStax Java Driver Unleashed!
Cassandra summit 2013 - DataStax Java Driver Unleashed!
 
TDC2016SP - Trilha DevOps Java
TDC2016SP - Trilha DevOps JavaTDC2016SP - Trilha DevOps Java
TDC2016SP - Trilha DevOps Java
 
MongoDB-SESSION03
MongoDB-SESSION03MongoDB-SESSION03
MongoDB-SESSION03
 
Exploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osqueryExploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osquery
 
ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)
 
Entity Framework Core & Micro-Orms with Asp.Net Core
Entity Framework Core & Micro-Orms with Asp.Net CoreEntity Framework Core & Micro-Orms with Asp.Net Core
Entity Framework Core & Micro-Orms with Asp.Net Core
 
Introduce leo-redundant-manager
Introduce leo-redundant-managerIntroduce leo-redundant-manager
Introduce leo-redundant-manager
 
Tutorial on Node File System
Tutorial on Node File SystemTutorial on Node File System
Tutorial on Node File System
 
Building .NET Apps using Couchbase Lite
Building .NET Apps using Couchbase LiteBuilding .NET Apps using Couchbase Lite
Building .NET Apps using Couchbase Lite
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with Xamarin
 
Hidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-PersistenceHidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-Persistence
 
Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v
Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v
Tipo virus espia con esto aprenderan a espiar a personas etc jeropas de mrd :v
 

Viewers also liked (20)

I os 06
I os 06I os 06
I os 06
 
I os 14
I os 14I os 14
I os 14
 
I os 16
I os 16I os 16
I os 16
 
I os 07
I os 07I os 07
I os 07
 
I os 15
I os 15I os 15
I os 15
 
I os 03
I os 03I os 03
I os 03
 
課程規畫
課程規畫課程規畫
課程規畫
 
I os 02
I os 02I os 02
I os 02
 
I os 08
I os 08I os 08
I os 08
 
I os 09
I os 09I os 09
I os 09
 
I os 11
I os 11I os 11
I os 11
 
I os 04
I os 04I os 04
I os 04
 
I os 05
I os 05I os 05
I os 05
 
I os 10
I os 10I os 10
I os 10
 
Bebepolis
BebepolisBebepolis
Bebepolis
 
Concumer behavior
Concumer behaviorConcumer behavior
Concumer behavior
 
цахим монгол
цахим монголцахим монгол
цахим монгол
 
Excample
ExcampleExcample
Excample
 
Gwiiyomi lyric
Gwiiyomi lyricGwiiyomi lyric
Gwiiyomi lyric
 
Tambah
TambahTambah
Tambah
 

Similar to iOS App Design Class 13: Network Data Retrieval and Parsing/TITLE

Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCAWhymca
 
Lecture 10 Networking on Mobile Devices
Lecture 10 Networking on Mobile DevicesLecture 10 Networking on Mobile Devices
Lecture 10 Networking on Mobile DevicesMaksym Davydov
 
RESTfull with RestKit
RESTfull with RestKitRESTfull with RestKit
RESTfull with RestKitTaras Kalapun
 
Parse London Meetup - Cloud Code Tips & Tricks
Parse London Meetup - Cloud Code Tips & TricksParse London Meetup - Cloud Code Tips & Tricks
Parse London Meetup - Cloud Code Tips & TricksHector Ramos
 
The Open Web and what it means
The Open Web and what it meansThe Open Web and what it means
The Open Web and what it meansRobert Nyman
 
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with InfrastructorGr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with InfrastructorStanislav Tiurikov
 
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docxWeb CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docxcelenarouzie
 
Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Satoshi Asano
 
DEF CON 23: Stick That In Your (root)Pipe & Smoke It
DEF CON 23: Stick That In Your (root)Pipe & Smoke ItDEF CON 23: Stick That In Your (root)Pipe & Smoke It
DEF CON 23: Stick That In Your (root)Pipe & Smoke ItSynack
 
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"ITGinGer
 
iPhone and Rails integration
iPhone and Rails integrationiPhone and Rails integration
iPhone and Rails integrationPaul Ardeleanu
 
Modern Android app library stack
Modern Android app library stackModern Android app library stack
Modern Android app library stackTomáš Kypta
 
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプCocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプMasayuki Nii
 
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core DataMatthew Morey
 
iOS Multithreading
iOS MultithreadingiOS Multithreading
iOS MultithreadingRicha Jain
 
Web Technologies - forms and actions
Web Technologies -  forms and actionsWeb Technologies -  forms and actions
Web Technologies - forms and actionsAren Zomorodian
 

Similar to iOS App Design Class 13: Network Data Retrieval and Parsing/TITLE (20)

Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
 
Android Networking
Android NetworkingAndroid Networking
Android Networking
 
Lecture 10 Networking on Mobile Devices
Lecture 10 Networking on Mobile DevicesLecture 10 Networking on Mobile Devices
Lecture 10 Networking on Mobile Devices
 
RESTfull with RestKit
RESTfull with RestKitRESTfull with RestKit
RESTfull with RestKit
 
Parse London Meetup - Cloud Code Tips & Tricks
Parse London Meetup - Cloud Code Tips & TricksParse London Meetup - Cloud Code Tips & Tricks
Parse London Meetup - Cloud Code Tips & Tricks
 
The Open Web and what it means
The Open Web and what it meansThe Open Web and what it means
The Open Web and what it means
 
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with InfrastructorGr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
 
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docxWeb CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
 
iOS5 NewStuff
iOS5 NewStuffiOS5 NewStuff
iOS5 NewStuff
 
Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Webエンジニアから見たiOS5
Webエンジニアから見たiOS5
 
DEF CON 23: Stick That In Your (root)Pipe & Smoke It
DEF CON 23: Stick That In Your (root)Pipe & Smoke ItDEF CON 23: Stick That In Your (root)Pipe & Smoke It
DEF CON 23: Stick That In Your (root)Pipe & Smoke It
 
Beyond the page
Beyond the pageBeyond the page
Beyond the page
 
Web sockets in Java
Web sockets in JavaWeb sockets in Java
Web sockets in Java
 
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
 
iPhone and Rails integration
iPhone and Rails integrationiPhone and Rails integration
iPhone and Rails integration
 
Modern Android app library stack
Modern Android app library stackModern Android app library stack
Modern Android app library stack
 
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプCocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
 
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core Data
 
iOS Multithreading
iOS MultithreadingiOS Multithreading
iOS Multithreading
 
Web Technologies - forms and actions
Web Technologies -  forms and actionsWeb Technologies -  forms and actions
Web Technologies - forms and actions
 

More from 信嘉 陳

More from 信嘉 陳 (13)

Processing 06
Processing 06Processing 06
Processing 06
 
Processing 05
Processing 05Processing 05
Processing 05
 
Processing 04
Processing 04Processing 04
Processing 04
 
Processing 03
Processing 03Processing 03
Processing 03
 
Processing 02
Processing 02Processing 02
Processing 02
 
Processing 01
Processing 01Processing 01
Processing 01
 
Processing 09
Processing 09Processing 09
Processing 09
 
Processing 08
Processing 08Processing 08
Processing 08
 
Processing 07
Processing 07Processing 07
Processing 07
 
I os 01
I os 01I os 01
I os 01
 
Google 街景
Google 街景Google 街景
Google 街景
 
社群網站 Facebook
社群網站 Facebook社群網站 Facebook
社群網站 Facebook
 
網路搜尋
網路搜尋網路搜尋
網路搜尋
 

iOS App Design Class 13: Network Data Retrieval and Parsing/TITLE

  • 2. 課程⼤大綱 • 擷取網路資料 • QV128:擷取網路上的 plist • NSURLConnection • QV129:載⼊入網路的⼤大圖檔,並能夠顯⽰示下載進度 • QV130:使⽤用 post 傳遞 • NSXMLParser • QV135:RSS 讀取網路資料 • Samples:SeismicXML, LazyTableImages • URL Scheme • QV121:呼叫系統內建的 App • QV122:⾃自訂 URL Scheme • QV123 + QV124 :openURL 功能測試『qrapp://』 • Samples:LaunchMe
  • 3. 擷取網路資料 • initWithContentsOfURL: ⼀一種⽅方法,屬於 NSString, NSArray, NSDictionary, ... 的⽅方法,直接將資料轉成 特定的資料型態 • NSURLConnection class ⼀一個類別,進⾏行 http 資料傳送 (get, post)
  • 4. 物件擷取網路資料的⽅方法 • NSString, NSMutableString + stringWithContentsOfURL: encoding: error: - initWithContentsOfURL: encoding: error: • NSArray, NSMutableArray + arrayWithContentsOfURL: - initWithContentsOfURL: • NSDictionary, NSMutableDictionary + dictionaryWithContentsOfURL: - initWithContentsOfURL: • NSData, NSMutableData + dataWithContentsOfURL: + dataWithContentsOfURL: options: error: - initWithContentsOfURL: - initWithContentsOfURL: options: error:
  • 5. Project QV128 讀取網路上的 plist 檔 ⽅方法⼀一:直接讀取 ⽅方法⼆二:加⼊入訊息通知 以進⾏行背景處理
  • 6. ViewController.h @interface ViewController : UIViewController { NSDictionary *dataDict; IBOutlet UILabel *display; } - (IBAction) btnStart:(id)sender; - (IBAction) btnStart2:(id)sender; - (void) loadFile; - (void) didDownloadDictionary: (NSNotification *)info; @end
  • 7. ViewController.m (1/3) ⽅方法⼀一:直接讀取網路資料 (同步⽅方式) - (IBAction) btnStart:(id)sender { display.text = @"......"; NSURL *url = [NSURL URLWithString:DictionaryURL]; dataDict = [[NSDictionary alloc] initWithContentsOfURL:url]; display.text = [dataDict description]; } 注意:等資料下載完畢後才會顯⽰示
  • 8. ViewController.m (2/3) ⽅方法⼆二:建⽴立訊息通知 - (IBAction) btnStart2:(id)sender { display.text = @"......"; // 產⽣生通知的物件 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didDownloadDictionary:) name:DidDownloadedNotification object:nil]; // 呼叫 [self performSelectorInBackground:@selector(loadFile) withObject:nil]; display.text = @"downloading......"; } 能在要求下載後繼續進⾏行程序
  • 9. ViewController.m (3/3) - (void) loadFile { NSURL *url = [NSURL URLWithString:DictionaryURL]; dataDict = [NSDictionary dictionaryWithContentsOfURL:url]; [[NSNotificationCenter defaultCenter] postNotificationName:DidDownloadedNotification object:self userInfo:dataDict]; } - (void) didDownloadDictionary: (NSNotification *)info { // 接收結果 dataDict = [info userInfo]; display.text = [dataDict description]; } 下載完畢後通知執⾏行
  • 12. 同步化 request // 初始化請求 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; // 設置URL [request setURL:[NSURL URLWithString:urlStr]]; // 設置HTTP⽅方法 (GET 或 POST) [request setHTTPMethod:@"GET"]; // 發送同步請求, 這裡的returnData就是傳回的資料內容 NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  • 13. ⾮非同步化 request NSMutableData*  buf  =  [[NSMutableData  alloc]  initWithLength:0]; NSURLConnection*  connection  =  [[NSURLConnection  alloc]  initWithRequest:req   delegate:self];   //  連線建⽴立成功收到回應時,  會觸發 -­‐  (void)connection:(NSURLConnection  *)connection  didReceiveResponse: (NSURLResponse  *)  aResponse;   //  每收到⼀一次網路封包資料,會觸發 -­‐  (void)connection:(NSURLConnection  *)connection  didReceiveData:(NSData  *)data {        [buf  appendData:data]; }   //  網路錯誤時觸發 -­‐  (void)connection:(NSURLConnection  *)connection  didFailWithError:(NSError   *)error;   //  全部資料接收完畢時觸發 -­‐  (void)connectionDidFinishLoading:(NSURLConnection  *)connection;
  • 14. Project QV129 載⼊入網路的⼤大圖檔,並能 夠顯⽰示下載進度 利⽤用 NSURLConnection 讀取網路資料 UIProgressView 進度顯⽰示
  • 15. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController { NSURLConnection *connect; IBOutlet UIImageView *img; IBOutlet UIProgressView *downloadProgress; NSMutableData *tempData; //下載時暫存⽤用的記憶體 long expectedLength; //檔案⼤大⼩小 } @end
  • 16. ViewController.m (1/4) 建⽴立連線讀取網路資料 - (void)viewDidLoad { downloadProgress.progress = 0.0; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL: [NSURL URLWithString:@"http://web.trtc.com.tw/img/ALL/Route2200/051.jpg"]]; [request setHTTPMethod:@"GET"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"Mobile Safari 1.1.3 (iPhone; U; CPU like Mac OS X; en)" forHTTPHeaderField:@"User-Agent"]; tempData = [NSMutableData alloc]; connect = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [super viewDidLoad]; }
  • 17. ViewController.m (2/4) 錯誤處理 - (void)connection:(NSURLConnection *)connection didFailWithError: (NSError *)error { //發⽣生錯誤 ! NSLog(@"發⽣生錯誤"); } 連線建⽴立成功處理 - (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)aResponse { //連線建⽴立成功,取得狀態 NSInteger status = (NSInteger)[(NSHTTPURLResponse *)aResponse statusCode]; NSLog(@"%d", status); expectedLength = [aResponse expectedContentLength]; //儲存檔案⻑⾧長度 }
  • 18. ViewController.m (3/4) 封包接收 -(void) connection:(NSURLConnection *)connection didReceiveData: (NSData *) incomingData { //收到封包,將收到的資料塞進緩衝中並修改進度條 ! [tempData appendData:incomingData]; double ex = expectedLength; downloadProgress.progress = [tempData length] / ex; }
  • 19. ViewController.m (4/4) 檔案下載完成處理 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { //檔案下載完成 //取得可讀寫的路徑 NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); ! NSString *path = [pathList objectAtIndex:0]; //加上檔名 path = [path stringByAppendingPathComponent: @"00.jpg"]; NSLog(@"儲存路徑:%@", path); ! ! //寫⼊入檔案 [tempData writeToFile:path atomically:NO]; tempData = nil; img.image = [UIImage imageWithContentsOfFile:path]; //顯⽰示圖⽚片在畫⾯面中 }
  • 20. Project QV130 利⽤用 NSURLConnection 的 post ⽅方法傳遞資料 WebView 顯⽰示取得的內容
  • 22. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController { NSURLConnection *connect; IBOutlet UIWebView *webView; IBOutlet UIProgressView *downloadProgress; NSMutableData *tempData; //下載時暫存⽤用的記憶體 long expectedLength; //檔案⼤大⼩小 } @end
  • 23. 建⽴立連線 (post) ⽅方法 ViewController.m (1/3) - (void)viewDidLoad { downloadProgress.progress = 0.0; NSString *post = @"submit=a &select2=030"; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; ! NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:@"http://web.trtc.com.tw/c/TicketALLresult.asp"]]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"Mobile Safari 1.1.3 (iPhone; U; CPU like Mac OS X; en)" forHTTPHeaderField:@"User-Agent"]; ! [request setHTTPBody:postData]; // 加上 post 的資料 ! tempData = [NSMutableData alloc]; connect = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [super viewDidLoad]; }
  • 24. ViewController.m (2/3) 錯誤處理 連線建⽴立成功處理 封包接收 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // 發⽣生錯誤 ! NSLog(@"發⽣生錯誤"); } - (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)aResponse { // 連線建⽴立成功 // 取得狀態 NSInteger status = (NSInteger)[(NSHTTPURLResponse *)aResponse statusCode]; NSLog(@"%d", status); expectedLength = [aResponse expectedContentLength]; //儲存檔案⻑⾧長度 } -(void) connection:(NSURLConnection *)connection didReceiveData: (NSData *) incomingData { // 收到封包,將收到的資料塞進緩衝中並修改進度條 ! [tempData appendData:incomingData]; double ex = expectedLength; downloadProgress.progress = [tempData length] / ex; }
  • 25. ViewController.m (3/3) 檔案下載完成處理 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // 內容取得完成 NSString *loadData = [[NSMutableString alloc] initWithData:tempData encoding:NSUTF8StringEncoding]; [webView loadHTMLString:loadData baseURL:nil]; NSLog(@"%@", loadData); tempData = nil; }
  • 29. Project QV135 RSS 讀取網路資料 讀取 RSS 網址,以 XML ⽅方 式剖析 (針對 rss 格式) 使⽤用 TableView 顯⽰示資料
  • 30. RSS 之內容範例 需要解析的格式 <item> <title></title> <link></link> <description></description> </item>
  • 32. NSXMLParser 的代理⽅方法 parser:(NSXMLParser *)parser 檢測到tag的開始 didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict parser:(NSXMLParser *)parser 檢測到內部的資料 foundCharacters:(NSString *)string parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 檢測到tag的結尾 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
  • 33. RSSParser 類別 將 rss ⽂文件轉換為⼀一個陣列 主程式 RSSParser 類別 NSMutableArray didStartElement: *result; title foundCharacters: link description title link didEndElement: description title link description
  • 34. #import <Foundation/Foundation.h> RSSParser.h // ⽤用來定義標籤的⾃自定義變數 // tagTitle = <title> // tagLink = <link> // tagDescription = <description> // tagunknown = 未知,不處理項⺫⽬目 typedef enum { tagTitle, tagLink, tagDescription, tagUnknown } RSSTag; @interface RSSParser : NSObject <NSXMLParserDelegate> { NSMutableDictionary *item; // 存放每筆news資料 RSSTag currentTag; // ⺫⽬目前正在解析的標籤 BOOL startItem; // 是否開始解析 } // 解析後所有的news @property (nonatomic, retain) NSMutableArray *result; - (id) initWithData:(NSData *) data; 解析內容後,將⽂文章條⺫⽬目 @end (含title, description, link) 以陣列儲存
  • 35. // 找到某個標籤的開始 - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes: (NSDictionary *)attributeDict { if([elementName isEqualToString:@"item"]) { startItem = YES; RSSParser.m (1/3) item = [NSMutableDictionary new]; } // 發現 item 後才開始解析 if(startItem) { if([elementName isEqualToString:@"title"]) { currentTag = tagTitle; } else if([elementName isEqualToString:@"description"]) { currentTag = tagDescription; } else if([elementName isEqualToString:@"link"]) (1) 當標籤開始時,分 { currentTag = tagLink; 別對內容為第⼀一層的 } else <item>,或是 <title>, { currentTag = tagUnknown; <description>, <link> } } 進⾏行處理 }
  • 36. // XML 的內⽂文 - (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { // 將空⽩白及換列符號去除 NSString *value = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // 若沒有任何內容或標籤未知則不處理 if([value length]==0 || currentTag==tagUnknown) RSSParser.m (2/3) { return; } // ⽐比對正在解析的標籤,並儲存該標籤內的⽂文字於 item 內 switch (currentTag) { case tagTitle: [item setValue:value forKey:@"title"]; break; case tagDescription: [item setValue:value forKey:@"description"]; break; (2) 處理標籤的內容: case tagLink: [item setValue:value forKey:@"link"]; 若之前的標籤是 <title>, break; <description>, <link> 之 default: break; ⼀一 ,則存⼊入陣列內 } }
  • 37. RSSParser.m (3/3) // 找到某個標籤的結尾 - (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if([elementName isEqualToString:@"item"]) { NSDictionary *parsedItem = [[NSDictionary alloc] initWithDictionary:item]; [self.result addObject:parsedItem]; item = nil; startItem = NO; } } (3) 讀取到標籤的結尾時, 便可將單筆項⺫⽬目記錄於 NSDictionary 內
  • 38. MasterViewController.h 主程式部分 #import <UIKit/UIKit.h> #import "RSSParser.h" @class DetailViewController; @interface MasterViewController : UITableViewController { NSArray *result; } @property (strong, nonatomic) DetailViewController *detailViewController; @end
  • 39. MasterViewController.m (1/2) - (void)viewDidLoad { [super viewDidLoad]; // 抓取資料 NSURL *url = [[NSURL alloc] initWithString:@"http://udn.com/udnrss/udpopular.xml"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; RSSParser *parser = [[RSSParser alloc] initWithData:data]; result = [[NSArray alloc] initWithArray:parser.result]; parser = nil; ****** 省略部分程式 ****** } 以同步⽅方式取得 全部原始資料
  • 40. MasterViewController.m (2/2) #pragma mark - Table View - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section { // return _objects.count; return [result count]; 資料已存在物件內,直接取⽤用 } // Customize the appearance of table view cells. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath { ****** 省略部分程式 ****** //NSDate *object = [_objects objectAtIndex:indexPath.row]; //cell.textLabel.text = [object description]; NSDictionary *item = [result objectAtIndex:indexPath.row]; cell.textLabel.text = [item objectForKey:@"title"]; return cell; }
  • 41. 範例觀摩:SeismicXML The SeismicXML sample application demonstrates how to use NSXMLParser to parse XML data. When you launch the application it downloads and parses an RSS feed from the United States Geological Survey (USGS) that provides data on recent earthquakes around the world. It displays the location, date, and magnitude of each earthquake, along with a color-coded graphic that indicates the severity of the earthquake. The XML parsing occurs on a background thread using NSOperation and updates the earthquakes table view with batches of parsed objects.
  • 42. 範例觀摩:LazyTableImages This sample demonstrates a multi-stage approach to loading and displaying a UITableView. It begins by loading the relevant text from an RSS feed so the table can load as quickly as possible, and then downloads the images for each row asynchronously so the UI is more responsive
  • 43. iOS 上使⽤用 JSON 參考資料 • Getting Started with JSON in iOS5 http://blogs.captechconsulting.com/blog/nathan-jones/getting-started-json-ios5/ • JavaScript Object Notation Serialization http://pragprog.com/magazines/2011-11/inside-ios-/ • 不要使⽤用 SBJSON (json-framework) http://blog.devtang.com/blog/2012/05/05/do-not-use-sbjson/
  • 45. URL Scheme • 以 openURL: 的⽅方法開啟外部的應⽤用程式 • 認識內建 App 的 URL Scheme • ⾃自建 URL Scheme
  • 46. 範例:URL Scheme • QV121:呼叫系統內建的 App • QV122:⾃自訂 URL Scheme • QV123:openURL 功能測試之呼叫程式 • QV124:openURL 功能測試之被呼叫程 式『qrapp://』
  • 47. Project QV121 URL Scheme 開啟 Safari、電話、簡訊、 Mail、iBooks 等
  • 48. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController - (IBAction) openSafari:(id)sender; - (IBAction) openGoogleMap1:(id)sender; - (IBAction) openGoogleMap2:(id)sender; - (IBAction) openPhone:(id)sender; - (IBAction) openSMS:(id)sender; - (IBAction) openMail:(id)sender; - (IBAction) openMailGood:(id)sender; - (IBAction) openIBooks:(id)sender; @end
  • 49. ViewController.m (1/5) - (IBAction) openSafari:(id)sender { NSString *stringURL = @"http://www.apple.com.tw/"; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; }
  • 50. ViewController.m (2/5) - (IBAction) openGoogleMap1:(id)sender { NSString *stringURL = @"http://maps.google.com/maps?q=Taiwan"; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; } 網址 - (IBAction) openGoogleMap2:(id)sender { NSString *title = @"台北101"; NSDecimalNumber *latitude = [NSDecimalNumber decimalNumberWithString:@"25.033671"]; // 緯度 NSDecimalNumber *longitude = [NSDecimalNumber decimalNumberWithString:@"121.564427"]; // 經度 NSInteger zoomValue = 12; NSString *stringURL = [NSString stringWithFormat:@"http:// maps.google.com/maps?q=%@@%1.6f,%1.6f&z=%d", [title stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [latitude floatValue], [longitude floatValue], zoomValue]; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; }
  • 51. ViewController.m (3/5) - (IBAction) openPhone:(id)sender { NSString *stringURL = @"tel:+8860212345678"; 電話 NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; } - (IBAction) openSMS:(id)sender { NSString *stringURL = @"sms:+12345678901"; 簡訊 NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; }
  • 52. ViewController.m (4/5) - (IBAction) openMail:(id)sender { NSString *stringURL = @"mailto:happy@mail.com"; 郵件 NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; } - (IBAction) openMailGood:(id)sender { // 預先填⼊入內⽂文 NSString *subject = @"標題"; NSString *msgBody = @"信件內⽂文"; NSString *emailAddress = @"hello@mail.com"; NSString *ccAddr = @"world@mail.com"; NSString *bccAddr = @"good@mail.com"; NSString *stringURL = [NSString stringWithFormat:@"mailto:%@?cc= %@&bcc=%@&subject=%@&body=%@", emailAddress, ccAddr, bccAddr, subject, msgBody]; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; }
  • 53. ViewController.m (5/5) - (IBAction) openIBooks:(id)sender { NSString *stringURL = @"itms-books://"; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; }
  • 54. ⾃自我練習 測試呼叫 Youtube 影⽚片 測試呼叫某個 AppStore 內的 app 問題:兩個應⽤用程式使⽤用相同的 URL Scheme 時會如何?
  • 55. Project QV122 ⾃自訂 URL Scheme 同時包含測試程式及被呼叫 程式
  • 56. (1) 選擇專案設定 (2) 新增 URL Type (3) 設定 URL Schemes
  • 57. @interface AppDelegate : UIResponder <UIApplicationDelegate, UIAlertViewDelegate> { UIAlertView *usageAlertView; } AppDelegate.h @end 先做⼀一個彈出視窗 (解說⽤用) AppDelegate.h - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSString *message = @"請按『Go』開啟Safari,並在Safari輸⼊入⼀一個開頭為 testurl:// 的 URL"; usageAlertView = [[UIAlertView alloc] initWithTitle:@"Usage" message:message delegate:self cancelButtonTitle:@"Go" otherButtonTitles:nil]; [usageAlertView show]; return YES; }
  • 58. AppDelegate.m (1/2) 再開出 Safari 應⽤用程式 (解說⽤用) - (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex: (NSInteger)buttonIndex { if(buttonIndex != -1) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.apple.com"]]; } }
  • 59. 系統呼叫執⾏行後 AppDelegate.m (2/2) 處理傳⼊入的訊息 - (BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if (!url) return NO; NSString *URLString = [url absoluteString]; if (!URLString) return NO; NSString *message = [NSString stringWithFormat:@"收到訊息: %@n誰呼叫 我: %@", URLString, sourceApplication]; UIAlertView *openAlert = [[UIAlertView alloc] initWithTitle:@"啟動訊 息" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [openAlert show]; return YES; }
  • 61. Project QV123 QV123+QV124 搭配測試 ⾃自訂 URL Scheme 此為呼叫程式
  • 62. ViewController.xib 指定呼叫的 ViewController.m URL Scheme - (IBAction) openMyApp:(id)sender { NSString *stringURL = @"qrapp://HelloWorld"; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url]; }
  • 63. Project QV124 QV123+QV124 搭配測試 ⾃自訂 URL Scheme 此為被呼叫後執⾏行的程式
  • 65. AppDelegate.m - (BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation: (id)annotation { if (!url) return NO; NSString *URLString = [url absoluteString]; if (!URLString) return NO; NSString *message = [NSString stringWithFormat:@"收到訊息: %@n誰呼叫 我: %@", URLString, sourceApplication]; UIAlertView *openAlert = [[UIAlertView alloc] initWithTitle:@"啟動訊 息" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [openAlert show]; return YES; }