iOSで削除されたデータを取得します。 パート2

これは記事の続きで、第6章「 iOS7の実際のアクションからリモートデータ取得する」の正式な翻訳です。



高度なHTTPリクエスト



これまではGETメソッドのみを使用しましたが、他のメソッドも利用できます。



最も一般的な2つのメソッド、GETとPOSTに焦点を当てます。



GETは最も単純なHTTP要求メソッドであり、ブラウザがWebページをロードするために使用するものです。 特定のURLにあるコンテンツを要求するために使用されます。 コンテンツは、たとえば、Webページ、写真、または音声ファイルです。 慣例により、GET要求は読み取り専用であり、W3C標準に従って、サーバー側を変更する操作では使用しないでください。 たとえば、フォームの送信や写真の送信にGETリクエストを使用しません。これらの操作にはサーバー側での変更が必要なためです(これらの場合はPOSTを使用します)。



POSTは、さらに処理するためのデータをURLに送信します。 パラメータは、GETと同じ形式を使用してリクエストの本文に含まれます。 たとえば、名前と年齢の2つのフィールドを含むフォームを投稿する場合は、リクエスト本文でname = Martin&age = 29のようなものを送信します。



パラメータを送信するこの方法は、Webページで広く使用されています。 最も一般的なケースはフォームです。 サイトのフォームに記入して[送信]をクリックすると、ほとんどの場合、リクエストはPOSTになります。



アプリケーションに戻り、得られた知識の一部を使用しましょう。 つまり、POSTを使用してジョークをランク付けしましょう。 投票(または+1または-1)をリモートサーバーに送信します。



最初に、必要なインターフェイスを作成します。 voteUpおよびvoteDownに投票するための2つのボタンを追加します。これらはそれぞれ、現在のジョークの評価を増減します。 また、「Chuck Who?」ボタンを追加します。このボタンには、Webビューのセクションの機能が表示されます。 THSViewController + Interface.hで、これらのメソッドの宣言を追加します。



THSViewController + Interface.h

#import "THSViewController.h" @interface THSViewController (Interface) - (void)addLabel; - (void)addButtonVoteUp; - (void)addButtonVoteDown; - (void)addButtonChuckWho; @end
      
      







THSViewController + Interface.mでは、これらのメソッドを実装しています。



THSViewController + Interface.m

 - (void) addButtonVoteUp { UIButton *voteUpButton = [UIButton buttonWithType:UIButtonTypeSystem]; [voteUpButton setTitle:@"Vote Up" forState:UIControlStateNormal]; CGFloat x = self.view.frame.size.width / 2.0 - 50.0f; CGFloat y = self.view.frame.size.height / 2.0 + 0.0f; voteUpButton.frame = CGRectMake(x, y, 100.0f, 50.0f); [voteUpButton addTarget:self action:@selector(voteUp) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:voteUpButton]; } -(void) addButtonVoteDown { UIButton *voteDownButton = [UIButton buttonWithType:UIButtonTypeSystem]; [voteDownButton setTitle:@"Vote Down" forState:UIControlStateNormal]; CGFloat x = self.view.frame.size.width / 2.0 - 50.0f; CGFloat y = self.view.frame.size.height / 2.0 + 50.0f; voteDownButton.frame = CGRectMake(x, y, 100.0f, 50.0f); [voteDownButton addTarget:self action:@selector(voteDown) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:voteDownButton]; } - (void)addButtonChuckWho { UIButton *chuckWhoButton = [UIButton buttonWithType:UIButtonTypeSystem]; [chuckWhoButton setTitle:@"Chuck Who?" forState:UIControlStateNormal]; CGFloat x = self.view.frame.size.width / 2.0 - 50.0f; CGFloat y = self.view.frame.size.height / 2.0 + 150.0f; chuckWhoButton.frame = CGRectMake(x, y, 100.0f, 50.0f); [chuckWhoButton addTarget:self action:@selector(chuckWho) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:chuckWhoButton]; }
      
      







THSViewController.hで、これらのボタンのアクション宣言を追加します。 addButtonVoteUpのvoteUp、addButtonVoteDownのvoteDown、addButtonChuckWhoのchuckWho。



THSViewController.h

 #import <UIKit/UIKit.h> @interface THSViewController : UIViewController @property (nonatomic, strong) UILabel *jokeLabel; - (void)voteUp; - (void)voteDown; - (void)chuckWho; @end
      
      







THSViewController.mでは、これらのメソッドのスタブを追加します。



THSViewController.m

 - (void)voteUp { } - (void)voteDown { } - (void)chuckWho { }
      
      







最後に、THSViewController.mのviewDidLoadメソッドで、インターフェイスを実装するメソッドを呼び出します。



THSViewController.m

 - (void)viewDidLoad { [super viewDidLoad]; [self addLabel]; [self addButtonVoteUp]; [self addButtonVoteDown]; [self addButtonChuckWho]; [self retrieveRandomJokes]; }
      
      







アプリケーションを起動すると、図のようなインターフェースが表示されます。 1





図1投票用のボタンが追加されたアプリケーションのインターフェース



次に、必要な機能を実装します。



まず、すべてのHTTP操作を担当するクラスTHSHTTPCommunicationクラスでPOST要求を行うための機能を実装します。 これを行うには、新しいpostURL:params:successBlockメソッドをTHSHTTPCommunication.mに追加します。これは、以前のretrieveURL:successBlockメソッドに似ています。



THSHTTPCommunication.m

 - (void)postURL:(NSURL *)url params:(NSDictionary *)params successBlock:(void(^)(NSData *))successBlock { self.successBlock = successBlock; //      POST  NSMutableArray *paramsArray = [NSMutableArray arrayWithCapacity:[params count]]; //       key=value  for (NSString *key in params) { [paramsArray addObject:[NSString stringWithFormat:@"%@=%@", key, params[key]]]; } //    ,   ,   & NSString *postBodyString = [paramsArray componentsJoinedByString:@"&"]; //  NSString  NSData ,      NSData *postBodyData = [NSData dataWithBytes:[postBodyString UTF8String] length:[postBodyString length]]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; //     POST [request setHTTPMethod:@"POST"]; //  content-type  form encoded [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"]; //    POST    [request setHTTPBody:postBodyData]; NSURLSessionConfiguration *conf = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:nil]; NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request]; [task resume]; }
      
      







POST要求データは、さまざまな形式を使用して構造化できます。 パラメーターは通常、フォームURLエンコード標準(W3C HTML標準に準拠)に従ってフォーマットされます。 この形式はデフォルトであり、多くのブラウザで広く使用されています。 このメソッドはNSDictionaryを引数として受け入れますが、NSDictionaryは内部Objective-Cタイプであるため、HTTP接続に送信できません。 HTTP接続を介して送信するには、認識可能な辞書の表現を作成する必要があります。 外国人とコミュニケーションをとるようなものです。 メッセージを普遍的な言語に翻訳します。図に示すように、普遍的な言語から母国語に翻訳します。 2. HTTPのユニバーサル言語はW3C標準であり、私たちの言語はObjective-Cであり、受信者の言語は私たちにとって未知です。



W3C標準では、各ケースで認識可能な表現の意味を定義するルールを定義しています。 この場合、標準のform-url-encoded部分に続くパラメーターを提示する必要があります(たとえば、param1 =var1¶m2= var2)。





図2メッセージングのメタファー



メソッドに戻り、上記のすべてをコードに変換する方法を見てみましょう。 まず、すべてのキーと値のペアを含む配列を作成し、次に&を使用して接続します。 結果の文字列は、NSDataクラスのインスタンスに変換され、投票の保存を担当するサーバーに送信されます。 NSURLRequestクラスのインスタンスを使用してPOSTリクエストを実行するには、content-typeと同じ方法でHTTPMethodをPOSTに設定します。



THSViewControllerクラスで使用するには、このメソッドを使用可能にする必要があります。



THSHTTPCommunication.h

 @interface THSHTTPCommunication : NSObject <NSURLSessionDownloadDelegate> - (void)retrieveURL:(NSURL *)url successBlock:(void(^)(NSData *))successBlock; - (void)postURL:(NSURL *)url params:(NSDictionary *)params successBlock:(void(^)(NSData *))successBlock; @end
      
      







THSHTTPCommunicationクラスにPOSTリクエストを実行するメソッドが含まれるようになったので、メインのTHSViewControllerから呼び出す必要があります。 次のリストに示すように、評価のアップグレードまたはダウングレードの方法を実装するときが来ました。



THSViewController.m

 - (void)voteUp { NSURL *url = [NSURL URLWithString:@"http://example.com/rater/vote"]; THSHTTPCommunication *http = [[THSHTTPCommunication alloc] init]; NSDictionary *params = @{@"joke_id":jokeID, @"vote":@(1)}; [http postURL:url params:params successBlock:^(NSData *response) { NSLog(@"Voted Up"); }]; } - (void)voteDown { NSURL *url = [NSURL URLWithString:@"http://example.com/rater/vote"]; THSHTTPCommunication *http = [[THSHTTPCommunication alloc] init]; NSDictionary *params = @{@"joke_id":jokeID, @"vote":@(-1)}; [http postURL:url params:params successBlock:^(NSData *response) { NSLog(@"Voted Down"); }]; }
      
      







要求で使用されるURLでNSURLオブジェクトを作成します。 THSHTTPCommunicationオブジェクトを作成します。 リクエストのパラメーターを決定します。 POSTリクエストを作成し、successBlockコールバックを設定します。



これらの機能は互いに非常に似ています。 最初に、リクエストに使用する完全なURLを定義してから、THSHTTPCommunicationクラスのインスタンスを作成します。 GETリクエストの前に同じことを行いました。 次に、パラメーターを保存するNSDictionaryを作成します。 これらのパラメーターをPOSTリクエストに含めることができるように、これらのパラメーターを以前に調査した形式(たとえば、joke_id =&vote = 1)に変換します。 前に見たように、この変換を担当するメソッドは、THSHTTPCommunicationクラスのインスタンスのpostURL:params:successBlockです。 そして、このメソッドを呼び出してリクエストを作成します。



アプリケーションを起動し、ジョークに賛成または反対するときに、コンソールにメッセージが表示されることを確認します。



2015-11-08 14:51:20.724 Test[1248:80442] Voted Up









または



2015-11-08 14:51:57.896 Test[1273:81833] Voted Down









サーバーへのPOSTリクエストが正常に完了したことを示します。



icndb APIとGET HTTP動詞を使用してジョークアプリケーションを作成しました。 これらのジョークをUIViewで表示することができ、すべてのジョークを高く評価できます。 これらのアクションは、POSTリクエストをリモートサーバーに送信します。



Webビューを使用して削除されたページを表示する



リモートサーバーにリクエストを送信する方法を学びました。 これは、Webページを表示する前にブラウザーが行うことです。 違いは答えの内容のみです。 Webページは、さまざまなマークアップタグをグラフィカルに定義する方法に関する一連のルールを定義するHTML標準を使用してフォーマットされます。 これらのルールは単純に見えますが、W3C標準に従ってページ全体を表示するのは難しいタスクです。 幸いなことに、iOSには、よく知られたWebKitエンジンを使用し、HTML / CSS / JavaScriptを解釈し、Webページ全体をUIView内に表示するUIWebViewコンポーネントが組み込まれています。



アプリケーションに戻りましょう。 Chuck Norrisのウェイクページを表示するwebViewを追加します。 彼女はボタンに触れるだけで混乱します。



最初に、UIViewControllerのサブクラスであるTHSWebViewControllerクラスを作成します。



THSWebViewController.h

 #import <UIKit/UIKit.h> @interface THSWebViewController : UIViewController @property (nonatomic, strong) UIWebView *webView; - (void)dismissView; //     - (void)back; //         - (void)forward; //   @end
      
      







THSWebViewController.m

 #import "THSWebViewController.h" #import "THSWebViewController+Interface.h" @interface THSWebViewController () @end @implementation THSWebViewController - (void)viewDidLoad { [super viewDidLoad]; [self addWebView]; [self addNavBar]; [self addTabBar]; } - (void)dismissView { //  } - (void)back { //  } - (void)forward { //  } @end
      
      







THSWebViewController + Interfaceカテゴリを作成し、Webビューインターフェイスを実装するためのコードを削除しました。



THSWebViewController + Interface.h

 #import "THSWebViewController.h" @interface THSWebViewController (Interface) - (void)addWebView; - (void)addNavBar; - (void)addTabBar; @end
      
      







THSWebViewController + Interface.m

 #import "THSWebViewController+Interface.h" @implementation THSWebViewController (Interface) - (void)addWebView { self.webView = [[UIWebView alloc] initWithFrame:self.view.frame]; [self.view addSubview:self.webView]; } - (void)addNavBar { CGFloat width = self.view.frame.size.width; CGRect frame = CGRectMake(0.0f, 0.0f, width, 64.0f); UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:frame]; self.navigationItem.title = @"Chuck Norris"; [navBar pushNavigationItem:self.navigationItem animated:NO]; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(dismissView)]; [self.view addSubview:navBar]; } - (void)addTabBar { CGFloat width = self.view.frame.size.width; CGRect frame = CGRectMake(0.0f, self.view.frame.size.height - 44.0f, width, 44.0f); UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:frame]; frame = CGRectMake(0.0f, 0.0f, 50.0f, 30.0f); UIBarButtonItem *backBtn = [[UIBarButtonItem alloc] initWithTitle:@"<" style:UIBarButtonItemStylePlain target:self action:@selector(back)]; UIBarButtonItem *forwardBtn = [[UIBarButtonItem alloc] initWithTitle:@">" style:UIBarButtonItemStylePlain target:self action:@selector(forward)]; [toolBar setItems:@[backBtn, forwardBtn]]; [self.view addSubview:toolBar]; } @end
      
      







ここで、THSViewController.mに、以前に宣言したchuckWhoメソッドの実装を追加します。 THSWebViewController.hファイルもインポートすることを忘れないでください。



THSViewController.m

 #import "THSViewController.h" #import "THSViewController+Interface.h" #import "THSHTTPCommunication.h" #import "THSWebViewController.h" … - (void)chuckWho { THSWebViewController *webViewController = [[THSWebViewController alloc] init]; [self presentViewController:webViewController animated:YES completion:nil]; }
      
      







これで、Chuck Whoボタンをクリックすると、図3のような空のWebビューが表示されます。





図3 モーダルウィンドウの空のWebビュー



機能を追加します。 これを行うには、THSWebViewControllerクラスのviewDidLoadに次のコードを追加します。



THSWebViewController.m

 - (void)viewDidLoad { [super viewDidLoad]; [self addWebView]; [self addNavBar]; [self addTabBar]; //   NSURLRequest  URL       NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:@"http://en.wikipedia.org/wiki/Chuck_Norris"]]; //       webView [self.webView loadRequest:request]; }
      
      







前と同様に、NSURLRequestオブジェクトを作成しましたが、NSURLSessionを使用してリクエストを送信する代わりに、UIWebViewクラスのloadRequestメソッドを使用します。これにより、すべての作業が実行されます。



最後に、dismissView、back、およびforwardメソッドの機能を実装する必要があります。



THSWebViewController.m

 - (void)dismissView { //  webView  ,    close [self dismissViewControllerAnimated:YES completion:nil]; } - (void)back { //     ,    back [self.webView goBack]; } - (void)forward { //     ,    forward [self.webView goForward]; }
      
      







すべてが完了したので、UIWebViewについてさらにいくつかのことを知ることが重要です。



ナビゲーションのフローを制御したい場合がいくつかあります。 たとえば、特定のコンテンツまたは特定のURLがいつ読み込まれたかを知りたいとします。



または、子供向けの安全なブラウザを実装している場合は、ユーザーが性別や麻薬などの特定の基準に該当するページを読み込むのをブロックしたいでしょう。 これらすべての種類のカスタマイズでは、UIWebViewDelegateプロトコルをUIWebViewデリゲートとして実装するクラスのインスタンスを作成します。 次のメソッドを実装できます。

webView:shouldStartLoadWithRequest:navigationType:

webViewDidStartLoad:

webViewDidFinishLoad:

webView:didFailLoadWithError:









最初の方法を使用すると、特定の要求を許可またはブロックすることにより、ナビゲーションのフローを制御できます。 他の3つのメソッドは情報イベントです(メソッド名からイベントの概要がわかります)。



それだけです! 図 4は、アプリケーションでWebビューがどのように表示されるかを示しています。





4. Webビューの最終ビュー



All Articles