【초학자용】모델 클래스를 만들어 JSON을 퍼스한다

소개



신인의 코드 리뷰를 실시하고 있어 아무래도 모델 클래스를 사용한 JSON 데이터의 퍼스를 할 수 없다, 데이타베이스로부터의 쿼리 퍼스를 할 수 없다, 같은 것이 많기 때문에 초학자용으로 기사를 씁니다.

여기까지 할까? 라고 할 정도의 절반 정도는 합니다.

환경


  • Xcode 7.3.1
  • AFNetworking 3.0
  • OS X 10.11.6
  • CocoaPods 0.39.0

  • CocoaPods는 도입된 전제로 진행됩니다.

    프로젝트 만들기





    Xcode를 닫습니다.



    닫혔다! ! 귀여운! !

    AFNetworking 설치


    $ cd /path/to/project/
    $ pod init
    $ vim Podfile
    

    Podfile
    target 'Sample' do
        pod 'AFNetworking', '~> 3.0'
    end
    
    $ pod install
    $ open /path/to/project/project.xcworkspace/
    

    사용할 API



    이번에는 도쿄도의 날씨를 사용합니다.

    샘플 코드



    ATS 관계에서 http에 액세스 할 수 없으므로 Info.plist에 씁니다.

    Info.plist
        <key>NSAppTransportSecurity</key>
        <dict>
            <key>NSAllowsArbitraryLoads</key>
                <true/>
        </dict>
    



    Info.plist에 키를 위와 같이 추가 할 수 있습니다.

    GET 요청



    모델 하는 것이 조금 번거롭기 때문에 ViewController에 써 버립니다.

    ViewController.m
    #import "ViewController.h"
    #import <AFNetworking/AFNetworking.h>
    
    @interface ViewController ()
    
    @property (weak, nonatomic) NSMutableArray *weatherDatas;
    
    @end
    
    static NSString *const accessUrl = @"http://weather.livedoor.com/forecast/webservice/json/v1";
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        _weatherDatas = [NSMutableArray array];
        _weatherDatas = [self getWeatherInfoData];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    - (NSMutableArray *)getWeatherInfoData {
        NSDictionary<NSString *, NSString *> *parameters = @{@"city" : @"130010"};
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        [manager GET:accessUrl
          parameters:parameters
            progress:nil
             success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
                 // ここに処理
             }
             failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                 NSLog(@"Error: %@", error);
             }
         ];
    }
    
    @end
    

    모델 클래스 작성



    File > New > File... 에서 파일을 만듭니다.
    iOS의 Source에서 Cocoa Touch Class가 선택되면 Next





    Weather 클래스를 만들었습니다.

    이번에는 「오늘」 「내일」 「내일」의 데이터를 취득하도록 합니다.

    Weather.h
    #import <Foundation/Foundation.h>
    
    @interface Weather : NSObject
    
    @property (strong, nonatomic) NSString *dateLabel;
    @property (strong, nonatomic) NSString *telop;
    @property (strong, nonatomic) NSString *imageUrl;
    
    @end
    

    대략 이런 느낌으로 둡시다!

    JSON 데이터 퍼스


    ViewController.m 에서 Weather.h 를 import합시다!
    상당히 기사를 만드는 것이 귀찮아져 왔기 때문에 여러가지 접습니다만 최종적으로는 이하와 같이 되면 좋을까? 라고 생각합니다.

    ViewController.m
    #import "ViewController.h"
    #import "Weather.h"
    #import <AFNetworking/AFNetworking.h>
    
    @interface ViewController ()
    
    typedef void (^apiCallback)(NSMutableArray<Weather *> *weatherDatas);
    
    @end
    
    static NSString *const accessUrl = @"http://weather.livedoor.com/forecast/webservice/json/v1";
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSDictionary<NSString *, NSString *> *parameters = @{@"city" : @"130010"};
        [self getWeatherInfoData:parameters callback:^(NSMutableArray<Weather *> *weatherDatas) {
            for (Weather *weather in weatherDatas) {
                NSLog(@"%@の天気は%@です。", weather.dateLabel, weather.telop);
            }
        }];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    - (void)getWeatherInfoData:(NSDictionary<NSString *, NSString *> *)parameters callback:(apiCallback)callback {
        NSMutableArray *weatherDatas = [NSMutableArray new];
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        [manager GET:accessUrl
          parameters:parameters
            progress:nil
             success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
                 for (NSDictionary<NSString *, NSString *> *forecasts in responseObject[@"forecasts"]) {
                     Weather *weather = [Weather new];
                     weather.dateLabel = forecasts[@"dateLabel"];
                     weather.telop = forecasts[@"telop"];
                     weather.imageUrl = [forecasts valueForKeyPath:@"image.url"];
                     [weatherDatas addObject:weather];
                 }
                 callback(weatherDatas);
             }
             failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                 NSLog(@"Error: %@", error);
                 callback(nil);
             }
         ];
    }
    
    @end
    

    NSLog 자체는 이런 식으로 나옵니다!

    NSLog 출력 결과
    2016-08-19 16:09:18.008 Sample[57209:10708282] 今日の天気は曇時々晴です。
    2016-08-19 16:09:18.008 Sample[57209:10708282] 明日の天気は曇時々雨です。
    2016-08-19 16:09:18.008 Sample[57209:10708282] 明後日の天気は曇りです。
    

    이번에는 이미지를 그대로 넣은 것만으로 하고 있습니다만, AFNetworking을 사용해 비동기로 이미지를 캐쉬하면서 표시하게 하는 것은 이하와 같이 한다

    ViewController.m
    #import <AFNetworking/UIImageView+AFNetworking.h>
    
    [imageView setImageWithURL:[NSURL URLWithString:@"http://example.com/image.png"]
                          placeholderImage:[UIImage imageNamed:@"placeholder"]];
    

    같으면 갈 수 있습니다.

    좋은 웹페이지 즐겨찾기