본문 바로가기
ios 뽀개기/objective-c

ios objective c - http 네트워크 통신 1

by 인생여희 2018. 11. 14.
반응형

ios objective c - http 네트워크 통신 1


이번포스팅에서는 ios 네트워크 통신에 대해서 간단히 정리한다. 

상황

클라이언트: ios 폰

중간에서 컨트롤하는 녀석: 퍼사드

서버: json 데이터형식


ios 네트워크에서 퍼사드 디자인 패턴을 알아본다. 퍼사드란 클라이언트와 서버 사이에 위치하는 녀석으로 클라이언트(앱)의 수정과 배포를 획기적으로 수월하게 해주는 녀석이다. 아래 코드는 날씨어플 버젼 1에서 버젼2로 코드수정을 했고, 주식어플 버젼1에서 버젼2로 코드 수정을하고 업데이트를 했다. 퍼사드 패턴을 써서 얼마나 쉽고 간결하게 처리를 해줬는지 확인했으면 ok. 코드에 주석을 달아 놓았다.


네비게이션


appdelegate.h

//

//  AppDelegate.h

//  1NetWork

//

//  Created by service on 2018. 11. 13..

//  Copyright © 2018년 service. All rights reserved.

//


#import <UIKit/UIKit.h>


//탭바 컨트롤러 델리게이트 추가해주기

@interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>


//윈도우 뷰

@property (strong, nonatomic) UIWindow *window;


//탭바

@property (strong, nonatomic) UITabBarController *tabBarController;


//버젼별 url을 할당받을 객체

@property (strong, nonatomic) NSURL                    *urlForWeatherVersion1;

@property (strong, nonatomic) NSURL                    *urlForWeatherVersion2;

@property (strong, nonatomic) NSURL                    *urlForStockVersion1;

@property (strong, nonatomic) NSURL                    *urlForStockVersion2;


@end



appdelegate.m

//

//  AppDelegate.m

//  1NetWork

//

//  Created by service on 2018. 11. 13..

//  Copyright © 2018년 service. All rights reserved.

//


#import "AppDelegate.h"

#import "WeatherViewController.h"

#import "StockViewController.h"


@interface AppDelegate ()

@end


@implementation AppDelegate


@synthesize window = _window;

@synthesize tabBarController = _tabBarController;

@synthesize urlForStockVersion1 = _urlForStockVersion1;

@synthesize urlForStockVersion2 = _urlForStockVersion2;

@synthesize urlForWeatherVersion1 = _urlForWeatherVersion1;

@synthesize urlForWeatherVersion2 = _urlForWeatherVersion2;


//앱이 실행될때 초기화 작업해주기!

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //윈도우 초기화 해주기

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    

    //테이블뷰컨트롤러 초기화 해서 네비게이션 컨트롤러에 넣어주기

    UIViewController *weatherVC = [[UINavigationController alloc] initWithRootViewController:[[WeatherViewController alloc]init]];

    UIViewController *stockVC = [[UINavigationController alloc] initWithRootViewController:[[StockViewController alloc]init]];

    

    //탭바를 초기화 하고 탭바에 위에서 만든 두가지 컨트롤러를 넣어주었다.

    self.tabBarController = [[UITabBarController alloc]init];

    self.tabBarController.viewControllers = [NSArray arrayWithObjects:weatherVC,stockVC, nil];

    

    //윈도우의 최상위 뷰는 탭바다.

    self.window.rootViewController = self.tabBarController;

    

    //윈도우를 보여줘라.

    [self.window makeKeyAndVisible];

    

    NSLog(@"didFinishLaunchingWithOptions 호출되었습니다.");

    

    

    //인디케이터 로직 호출 해야됨 ~~!

    

    [self loadServiceLocator];

    return YES;

}


//서비스 로케이터 호출

-(void)loadServiceLocator {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSError *error = nil;

        

        //url을 넣으면 해당 데이터를 받는다

        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://api.myjson.com/bins/18ckhy"]

                                             options:NSDataReadingUncached

                                               error:&error];

        //성공

        if (error == nil) {

            //json 데이터 파싱해서 dictionary에 할당.

            NSDictionary *locationDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];

            

                if (error == nil){

                    //findURLForServiceNamed() 메서드에 각각의 파라미터를 넣으면 해당 url을 리턴해준다 : 위에서 받은 locationDictionary 데이터 넣어줌.

                    self.urlForWeatherVersion1 = [self findURLForServiceNamed:@"weather" versoin:1 inDictionary:locationDictionary];

                    self.urlForWeatherVersion2 = [self findURLForServiceNamed:@"weather" versoin:2 inDictionary:locationDictionary];

                    self.urlForStockVersion1 = [self findURLForServiceNamed:@"stockQuote" versoin:1 inDictionary:locationDictionary];

                    self.urlForStockVersion2 = [self findURLForServiceNamed:@"stockQuote" versoin:2 inDictionary:locationDictionary];


                }else{

                    //에러발생:url연결 되었지만 파싱은 안될때

                        NSLog(@" service locator를 파싱할 수 없습니다!. error: %@", error);

                        dispatch_async(dispatch_get_main_queue(), ^{

                            [[[UIAlertView alloc] initWithTitle:@"error"

                                                        message:@"서비스 로케이터를 파싱할수 없습니다."

                                                       delegate:nil

                                              cancelButtonTitle:@"ok"

                                              otherButtonTitles:nil]show];

                        });

                }

            

        }else{

            //url연결 되지 않을때

            NSLog(@"서비스 로케이터를 로드할 수 없습니다. error: %@", error);

            dispatch_async(dispatch_get_main_queue(), ^{

                [[[UIAlertView alloc] initWithTitle:@"Error"

                                            message:@"서비스 로케이터를 로드할 수 없습니다.  url 업데이트해야 되는거 아닌가요?"

                                           delegate:nil

                                  cancelButtonTitle:@"OK"

                                  otherButtonTitles:nil] show];

            });

        }

    });

}



-(NSURL*) findURLForServiceNamed:(NSString*)serviceName versoin:(NSInteger)versionNumber inDictionary:(NSDictionary*)locatorDictionary{

    //json형식의 파일에서 배열형식의 데이터를 읽어 온다.

    NSArray *service = [locatorDictionary objectForKey:@"services"];

    

    //딕셔너리 형식의 데이터 추출

    for (NSDictionary *serviceInfo in service) {

        NSString *name = [serviceInfo objectForKey:@"name"];

        NSInteger version = [[serviceInfo objectForKey:@"version"] intValue];

        

        

        //추출된 데이터와 파라미터로 넘어온 이름, 버젼을 비교해서 같으면 해당 url을 넘겨준다.

        if ([name caseInsensitiveCompare:serviceName] == NSOrderedSame && version == versionNumber) {

            return [NSURL URLWithString:[serviceInfo objectForKey:@"url"]];

        }

    }

    

    return nil;

}



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

    //서비스 로케이터 로드

     NSLog(@"applicationDidBecomeActive 호출되었습니다.");

    [self loadServiceLocator];

}



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

    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.

}



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

    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

}



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

    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

}





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

    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

}



@end


weathercontroller.h

//

//  WeatherViewController.h

//  1NetWork

//

//  Created by service on 2018. 11. 13..

//  Copyright © 2018년 service. All rights reserved.

//


#import <UIKit/UIKit.h>


@interface WeatherViewController : UITableViewController

@end


weathercontroller.m

//

//  WeatherViewController.m

//  1NetWork

//

//  Created by service on 2018. 11. 13..

//  Copyright © 2018년 service. All rights reserved.

//


#import "WeatherViewController.h"

#import "AppDelegate.h"


@interface WeatherViewController (){

    UISegmentedControl      *versionSelector;

    NSString                *v1_city;

    NSString                *v1_state;

    NSString                *v1_temperature;

    

    NSString            *v2_city;

    NSString            *v2_state;

    NSInteger            v2_temperature;

    NSString            *v2_conditions;

    

}


-(void)versionChanged:(id)sender;

-(void)loadVersion1Weather;

@end




@implementation WeatherViewController


//초기화 작업

-(id)init{

    self = [super initWithStyle:UITableViewStyleGrouped];

    if(self){

        //탭바의 아이템과 이미지를 초기화 하고 넘겨준다.

        self.tabBarItem.title = NSLocalizedString(@"Weather", @"Weather");

        self.tabBarItem.image = [UIImage imageNamed:@"weather"];

    }

    return self;

}



- (void)viewDidLoad {

    [super viewDidLoad];

    

    NSLog(@"WeatherViewController 호출되었습니다.");

    

    //version selector 설정 : (제일 상단에 네비게이션 바를 셋팅한다.)

    versionSelector = [[UISegmentedControl alloc] initWithItems:

                       [NSArray arrayWithObjects:

                        NSLocalizedString(@"Version 1", @"Version 1"),

                        NSLocalizedString(@"Veresion 2", @"Version 2"),nil]];

    versionSelector.segmentedControlStyle = UISegmentedControlStyleBar;

    versionSelector.selectedSegmentIndex = 0;

    

    [versionSelector addTarget:self

                        action:@selector(versionChanged:)

              forControlEvents:UIControlEventValueChanged];

    self.navigationItem.titleView = versionSelector;

}



//버젼 변경

-(void)versionChanged:(id)sender{

    [self.tableView reloadData];

}


//weather1 데이터 로드

-(void)loadVersion1Weather{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];

        

        if (appDelegate.urlForStockVersion1 != nil) {

            NSError *error = nil;

            //appDelegate의 urlForWeatherVersion1 변수가 해당 url을 가지고 있음.

            //넣어주고 데이터를 받는다.

            NSData *data = [NSData dataWithContentsOfURL:appDelegate.urlForWeatherVersion1

                                                 options:NSDataReadingUncached

                                                   error:&error];

            if (error == nil) {

                //딕셔너리에 넣어준다.

                NSDictionary *weatherDictionary = [NSJSONSerialization JSONObjectWithData:data

                                                                                  options:NSJSONReadingMutableLeaves

                                                                                    error:&error];

                if (error == nil) {

                    //딕셔너리에서 키값을 이용해서 데이터를 하나씩 추출한다.

                    v1_city = [weatherDictionary objectForKey:@"city"];

                    v1_state = [weatherDictionary objectForKey:@"state"];

                    v1_temperature = [weatherDictionary objectForKey:@"currentTemperature"];

                    

                    //update the table on the ui thread

                    dispatch_async(dispatch_get_main_queue(), ^{

                        //테이블을 리로드 해준다!

                        [self.tableView reloadData];

                    });

                    

                }else{

                    [self showParseError];

                }

            } else{

                [self showLoadError];

            }

        }else{

             [self showLoadError];

        }

        

    });

}


- (void)loadVersion2Weather {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

        

        if (appDelegate.urlForWeatherVersion2 != nil) {

            NSError *error = nil;

            NSData *data = [NSData dataWithContentsOfURL:appDelegate.urlForWeatherVersion2

                                                 options:NSDataReadingUncached

                                                   error:&error];

            

            if (error == nil) {

                NSDictionary *weatherDictionary = [NSJSONSerialization JSONObjectWithData:data

                                                                                  options:NSJSONReadingMutableLeaves

                                                                                    error:&error];

                

                if (error == nil) {

                    v2_city = [weatherDictionary objectForKey:@"city"];

                    v2_state = [weatherDictionary objectForKey:@"state"];

                    v2_temperature = [[weatherDictionary objectForKey:@"currentTemperature"] intValue];

                    v2_conditions = [weatherDictionary objectForKey:@"currentConditions"];

                    

                    // update the table on the UI thread

                    dispatch_async(dispatch_get_main_queue(), ^{

                        [self.tableView reloadData];

                    });

                    

                } else {

                    NSLog(@"Unable to parse weather because of error: %@", error);

                    [self showParseError];

                }

                

            } else {

                [self showLoadError];

            }

            

        } else {

            [self showLoadError];

        }

    });

}


//로드할때 에러발생

-(void)showLoadError

{

    dispatch_async(dispatch_get_main_queue(), ^{

       [[[UIAlertView alloc] initWithTitle:@"error"

                                   message:@"unable to load weather data"

                                  delegate:nil

                         cancelButtonTitle:@"ok"

                         otherButtonTitles:nil] show];

        

    });

}


//파싱할때 에러 발생

-(void)showParseError

{

    dispatch_async(dispatch_get_main_queue(), ^{

        [[[UIAlertView alloc] initWithTitle:@"Error"

                                    message:@"Unable to parse weather data."

                                   delegate:nil

                          cancelButtonTitle:@"OK"

                          otherButtonTitles:nil] show];

    });

}



- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


#pragma mark - Table view data source


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

#warning Incomplete implementation, return the number of sections

    return 2;

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

#warning Incomplete implementation, return the number of rows

    

    //색션이 0일때

    if (section == 0) {

        //세그먼트가 0이면 행의 갯수는 3

        if (versionSelector.selectedSegmentIndex == 0) {

            return 3;

        } else if(versionSelector.selectedSegmentIndex == 1) {

            return 4;

        }

        

        //색션이 2일때 refresh button

    } else if(section == 1){

        return 1;

    }

    

    return 0;

}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = nil;

    

    //첫번째 섹션일때

    if(indexPath.section == 0){

        static NSString *infoCellId = @"infoCell";

        cell = [tableView dequeueReusableCellWithIdentifier:infoCellId];

        

        if (cell == nil) {

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:infoCellId];

            cell.selectionStyle = UITableViewCellSelectionStyleNone;

        }

        

        //첫번째 섹션에 첫번째 세그먼트 : version1

        if(versionSelector.selectedSegmentIndex == 0){

            if (indexPath.row == 0) {

                cell.textLabel.text = NSLocalizedString(@"City", @"City");

                cell.detailTextLabel.text = v1_city;

            } else if(indexPath.row == 1){

                cell.textLabel.text = NSLocalizedString(@"State", @"State");

                cell.detailTextLabel.text = v1_state;

            }else if(indexPath.row == 2){

                cell.textLabel.text = NSLocalizedString(@"Temperature", @"Temperature");

                cell.detailTextLabel.text = [v1_temperature stringByAppendingString:@"\u00B0F"];

            }

        }

        //첫번째 섹션에 두번째 세그번트 : version2

     else if(versionSelector.selectedSegmentIndex == 1){

        

            // city

        if (indexPath.row == 0) {

            cell.textLabel.text = NSLocalizedString(@"City", @"City");

            cell.detailTextLabel.text = v2_city;

            

            // state

        } else if (indexPath.row == 1) {

            cell.textLabel.text = NSLocalizedString(@"State", @"State");

            cell.detailTextLabel.text = v2_state;

            

            // temperature

        } else if (indexPath.row == 2) {

            cell.textLabel.text = NSLocalizedString(@"Temperature", @"Temperature");

            cell.detailTextLabel.text = [NSString stringWithFormat:@"%i\u00B0F", v2_temperature];

            

            // conditions

        } else if (indexPath.row == 3) {

            cell.textLabel.text = NSLocalizedString(@"Conditions", @"Conditions");

            cell.detailTextLabel.text = v2_conditions;

        }

        

     }

        

        //두번째 섹션

    }else if(indexPath.section == 1){

        static NSString *buttonCellId = @"buttonCell";

        cell = [tableView dequeueReusableCellWithIdentifier:buttonCellId];

        if (cell == nil) {

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:buttonCellId];

        }

        cell.textLabel.text = NSLocalizedString(@"Refresh Richmond, VA", @"Refresh Richmond, VA");

        cell.textLabel.textAlignment = UITextAlignmentCenter;

        cell.textLabel.textColor = [UIColor blueColor];

    }

    

    return cell;

}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    

    if (indexPath.section == 1) {

        

        //version1

        if (versionSelector.selectedSegmentIndex == 0) {

        

            [self loadVersion1Weather];

        //version2

        }else if(versionSelector.selectedSegmentIndex == 1){

            [self loadVersion2Weather];

        }

    }

}


@end


stock.h

//

//  StockViewController.h

//  1NetWork

//

//  Created by service on 2018. 11. 13..

//  Copyright © 2018년 service. All rights reserved.

//


#import <UIKit/UIKit.h>


@interface StockViewController : UITableViewController

@end



stock.m

//

//  StockViewController.m

//  1NetWork

//

//  Created by service on 2018. 11. 13..

//  Copyright © 2018년 service. All rights reserved.

//


#import "StockViewController.h"

#import "AppDelegate.h"

@interface StockViewController (){

    UISegmentedControl *versionSelector;

    NSString            *v1_symbol;

    NSString            *v1_name;

    NSNumber            *v1_currentPrice;

    

    NSString            *v2_symbol;

    NSString            *v2_name;

    NSNumber            *v2_currentPrice;

    NSNumber            *v2_openingPrice;

    NSString            *v2_percentageChange;

}

- (void)versionChanged:(id)sender;

- (void)loadVersion1Stock;

- (void)loadVersion2Stock;

@end


@implementation StockViewController



-(id)init{

    self = [super initWithStyle:UITableViewStyleGrouped];

    if(self){

        //탭바의 아이템과 이미지를 초기화 하고 넘겨준다.

        self.tabBarItem.title = NSLocalizedString(@"Stock Quote", @"Stock Quote");

        self.tabBarItem.image = [UIImage imageNamed:@"stock"];

        

        //변수 초기화

        v1_symbol = @"";

        v1_name = @"";

        v1_currentPrice = nil;

        

        v2_symbol = @"";

        v2_name = @"";

        v2_currentPrice = nil;

        v2_openingPrice = nil;

        v2_percentageChange = @"";

        

    }

    return self;

}


- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"StockViewController 호출되었습니다.");

    // Uncomment the following line to preserve selection between presentations.

    // self.clearsSelectionOnViewWillAppear = NO;

    

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.

    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

}


- (void)versionChanged:(id)sender {

    [self.tableView reloadData];

}


- (void)loadVersion1Stock {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

       AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

        if (appDelegate.urlForStockVersion1 != nil) {

            NSError *error = nil;

            NSData *data = [NSData dataWithContentsOfURL:appDelegate.urlForStockVersion1

                                                 options:NSDataReadingUncached

                                                   error:&error];

            

            if (error == nil) {

                NSDictionary *stockDictionary = [NSJSONSerialization JSONObjectWithData:data

                                                                                options:NSJSONReadingMutableLeaves

                                                                                  error:&error];

                

                if (error == nil) {

                    v1_symbol = [stockDictionary objectForKey:@"symbol"];

                    v1_name = [stockDictionary objectForKey:@"name"];

                    v1_currentPrice = [NSNumber numberWithFloat:[[stockDictionary objectForKey:@"currentPrice"] floatValue]];

                    

                    // update the table on the UI thread

                    dispatch_async(dispatch_get_main_queue(), ^{

                        [self.tableView reloadData];

                    });

                    

                } else {

                    NSLog(@"Unable to parse stock quote because of error: %@", error);

                    [self showParseError];

                }

                

            } else {

                [self showLoadError];

            }

            

        } else {

            [self showLoadError];

        }

        

    

    });

}


- (void)loadVersion2Stock {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];


        if (appDelegate.urlForStockVersion2 != nil) {

            NSError *error = nil;

            NSData *data = [NSData dataWithContentsOfURL:appDelegate.urlForStockVersion2

                                                 options:NSDataReadingUncached

                                                   error:&error];


            if (error == nil) {

                NSDictionary *stockDictionary = [NSJSONSerialization JSONObjectWithData:data

                                                                                options:NSJSONReadingMutableLeaves

                                                                                  error:&error];


                if (error == nil) {

                    v2_symbol = [stockDictionary objectForKey:@"symbol"];

                    v2_name = [stockDictionary objectForKey:@"name"];

                    v2_openingPrice = [stockDictionary objectForKey:@"openingPrice"];

                    v2_currentPrice = [stockDictionary objectForKey:@"currentPrice"];

                    v2_percentageChange = [stockDictionary objectForKey:@"percentageChange"];


                    // update the table on the UI thread

                    dispatch_async(dispatch_get_main_queue(), ^{

                        [self.tableView reloadData];

                    });


                } else {

                    NSLog(@"Unable to parse stock quote because of error: %@", error);

                    [self showParseError];

                }


            } else {

                [self showLoadError];

            }


        } else {

            [self showLoadError];

        }

    });

}

- (void)showLoadError {

    // inform the user on the UI thread

    dispatch_async(dispatch_get_main_queue(), ^{

        [[[UIAlertView alloc] initWithTitle:@"Error"

                                    message:@"Unable to load stock data."

                                   delegate:nil

                          cancelButtonTitle:@"OK"

                          otherButtonTitles:nil] show];

    });

}


- (void)showParseError {

    // inform the user on the UI thread

    dispatch_async(dispatch_get_main_queue(), ^{

        [[[UIAlertView alloc] initWithTitle:@"Error"

                                    message:@"Unable to parse stock data."

                                   delegate:nil

                          cancelButtonTitle:@"OK"

                          otherButtonTitles:nil] show];

    });

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


#pragma mark - Table view data source


//색션 개수

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {


    return 2;

}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


    // stock info

    if (section == 0) {

        

        // version 1 has 3 cells of information

        if (versionSelector.selectedSegmentIndex == 0) {

            return 3;

            

            // version 2 has 5 cells of information

        } else if (versionSelector.selectedSegmentIndex == 1) {

            return 5;

        }

        

        // refresh button

    } else if (section == 1) {

        return 1;

    }

    return 0;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = nil;

    NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];

    currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;

    

    // info group

    if (indexPath.section == 0) {

        static NSString *infoCellId = @"infoCell";

        cell = [tableView dequeueReusableCellWithIdentifier:infoCellId];

        

        if (cell == nil) {

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:infoCellId];

            cell.selectionStyle = UITableViewCellSelectionStyleNone;

        }

        

        // version 1

        if (versionSelector.selectedSegmentIndex == 0) {

            

            // symbol

            if (indexPath.row == 0) {

                cell.textLabel.text = @"Symbol";

                cell.detailTextLabel.text = v1_symbol;

                

                // name

            } else if (indexPath.row == 1) {

                cell.textLabel.text = @"Name";

                cell.detailTextLabel.text = v1_name;

                

                // price

            } else if (indexPath.row == 2) {

                cell.textLabel.text = @"Price";

                cell.detailTextLabel.text = [currencyFormatter stringFromNumber:v1_currentPrice];

            }

            

            

            // version 2

        } else if (versionSelector.selectedSegmentIndex == 1) {

            

            // symbol

            if (indexPath.row == 0) {

                cell.textLabel.text = @"Symbol";

                cell.detailTextLabel.text = v2_symbol;

                

                // name

            } else if (indexPath.row == 1) {

                cell.textLabel.text = @"Name";

                cell.detailTextLabel.text = v2_name;

                

                // opening price

            } else if (indexPath.row == 2) {

                cell.textLabel.text = @"Opening Price";

                cell.detailTextLabel.text = [currencyFormatter stringFromNumber:v2_openingPrice];

                

                // current price

            } else if (indexPath.row == 3) {

                cell.textLabel.text = @"Current Price";

                cell.detailTextLabel.text = [currencyFormatter stringFromNumber:v2_currentPrice];

                

                // percentage change

            } else if (indexPath.row == 4) {

                cell.textLabel.text = @"Percent Change";

                cell.detailTextLabel.text = v2_percentageChange;

            }

        }

        

        // button group

    } else if (indexPath.section == 1) {

        static NSString *buttonCellId = @"buttonCell";

        cell = [tableView dequeueReusableCellWithIdentifier:buttonCellId];

        

        if (cell == nil) {

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:buttonCellId];

        }

        

        cell.textLabel.text = @"Refresh AAPL";

        cell.textLabel.textAlignment = UITextAlignmentCenter;

        cell.textLabel.textColor = [UIColor blueColor];

    }

    

    return cell;

}



#pragma mark - UITableViewDelegate


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    

    if (indexPath.section == 1) {

        

        // version 1

        if (versionSelector.selectedSegmentIndex == 0) {

            [self loadVersion1Stock];

            

            // version 2

        } else if (versionSelector.selectedSegmentIndex == 1) {

            [self loadVersion2Stock];

        }

    }

}


@end


중간에서 조정해주는 퍼사드! (url은 직접 로컬에서 서버를 돌려서 실행해본다.)


{

  "services": [

    {

      "name": "stockQuote",

      "url": "https://api.myjson.com/bins/u25za",

      "version": 1

    },

    {

      "name": "stockQuote",

      "url": "https://api.myjson.com/bins/1cilqe",

      "version": 2

    },

    {

      "name": "weather",

      "url": "https://api.myjson.com/bins/pap52",

      "version": 1

    },

    {

      "name": "weather",

      "url": "https://api.myjson.com/bins/pw4qu",

      "version": 2

    }

  ]

}



날씨 버젼1 데이터

{

  "city": "Richmond",

  "state": "Virginia",

  "currentTemperature": "63"

}

날씨 버젼2 데이터

{

  "city": "Richmond",

  "state": "Virginia",

  "currentTemperature": 63,

  "currentConditions": "Mostly Cloudy"

}

주식 버젼1 데이터

{

  "symbol": "AAPL",

  "name": "Apple Inc.",

  "currentPrice": "-2.92%"

}

주식 버젼2 데이터

{

  "symbol": "AAPL",

  "name": "Apple Inc.",

  "openingPrice": 545.31,

  "currentPrice": 530.12,

  "percentageChange": "-2.92%"

}


잘돌아가는지 확인! 










반응형

댓글