레이블이 jSON인 게시물을 표시합니다. 모든 게시물 표시
레이블이 jSON인 게시물을 표시합니다. 모든 게시물 표시

2016년 4월 21일 목요일

swift 에서 URLRequest, JSON 파싱 (REST API 클라이언트 개발)

2013년 앱개발 알바를 할때는 다음과 같은 기록을 남겼다.

http://mtsparrow.blogspot.kr/2013/04/ios-json.html

2016년 swift 에서는 어떻게 해야 하는가?

http://mtsparrow.blogspot.kr/2016/03/cocoapod.html

코코아 팟을 이용해서 오픈 소스 중에 JSON과  URLRequest를 편리 하게 해주는
오픈 소스 두개를 추가 한다.

SwiftyJSON
https://github.com/swiftjson/SwiftJson


Alamofire

https://github.com/Alamofire/Alamofire


다음은 간단한 예제 코드이다.

    var arrRes = [[String:AnyObject]]() // Array of dictionary
    var reqParam = [ String:AnyObject]()


func RequestRestAPI() {
        // 요청 키 밸류
        reqParam = [
            "--":"--",
            "--":"--",
            "--":"--",
            "--":"--",
            "--":"--",
            "--":"--",
            "--":"--",
            "--":"--",
            "--":"--"
        ]
        
        print(reqParam)
        

        ActIndicator.startAnimating() 
        Alamofire.request(.POST, "https://URL~~~blahblah/api/", parameters: reqParam).responseJSON { (responseData) -> Void in
            self.ActIndicator.stopAnimating()
            if responseData.result.value != nil {
                let swiftyJsonVar = JSON(responseData.result.value!)
                
                print(swiftyJsonVar["result"])
                print(swiftyJsonVar["message"])
                if swiftyJsonVar["result"].stringValue == "true" {
                    if let resData = swiftyJsonVar["data"].arrayObject {
                        self.arrRes = resData as! [[String:AnyObject]]
                    }
                    print(self.arrRes)
                    
                    // 응답 성공 arrRes에  딕셔너리에서 결과 키 밸류를 이용해서 처리 한다.
                    
                } else {
                    // 에러 응답 처리
                }
            } else {
               // 네트워크 에러 처리

            }
        }

    }


간단하게 설명을 하자면

ActIndicator.startAnimation()은 엑티비티 인디케이터를 네트워크 시작시 에니메이션을 시작 한다.

Alamofire.request 로 REST API에 URL을 주고 reqParam으로 정의된 키벨류를 전달 한다.

네트워크 요청이 완료되면 Alamofire.request의 블럭 코딩 부분이 수행되며 액티비티 인디케이터 에니 메이션을 종료 하고 SwiftyJSON을 이용한 결과 데이터를 얻어내면 된다.

위 예제는 응답 결과를 JSON을 받고 약속된 프로코톨로 result, message, data 키로 받게 되어 있다.
REST API마다 JSON의 형태는 다를 것이고 이경우 result, message, data는 동일 하며
data의 형태는 다시 키벨류 쌍으로 REST API tag의 따라 다양하게 정의된 경우 이다.

// 응답 성공의 경우 data의 arrayObject를 self.arrRes에 할당 했으며 데이터 타입은 String:AnyObject이다.

정의된 String Key로 값을 접근하면 된다.


2015년 12월 2일 수요일

계층형에 내부 반복 (Array) 로 복잡한 json 문자열 생성하기

이번 미션에서는 어떠한 데이터를 받아서 json문자열을 생성 해야  한다.

지금 까지는 간단한 key :  value 형태의 json 문자열을 생성하여  WAS통신 하는 앱을 개발 했는데 그것은 간단한 NSArray 의 key value를 SBJson 모듈에 넣어서 생성 하면 간단 했다.

이번의 경우는

     timezone
     activity
        -- startTime
        -- stopTime
        -- calorie
        -- detail
            --startTime
            --stopTime
            --stepCnt
            -- distance
            -- mode
     sleep
        -- startTime
        -- stopTime
        -- calorie
        -- detail
            -- startTime
            -- stopTime
            -- settingstartTime
            -- settingstopTime
     

            mode


위와 같은 json 형태가 되는데 active 의 하위 key가 있고 그중 detail은 또 하위를 가지며
detal은 mode에 따라서 여러번 반복된다.
마찬가지로 sleep도 마찬가지이다.


    //sleep.detail
    NSMutableDictionary * sleep_detail1 = [[NSMutableDictionary alloc] init];
    [sleep_detail1 setValue:@"200" forKey:@"startTime"];
    [sleep_detail1 setValue:@"200" forKey:@"stopTime"];
    [sleep_detail1 setValue:@"200" forKey:@"settingstartTime"];
    [sleep_detail1 setValue:@"200" forKey:@"settingstopTime"];
    [sleep_detail1 setValue:@"Awake" forKey:@"mode"];

    NSMutableDictionary * sleep_detail2 = [[NSMutableDictionary alloc] init];
    [sleep_detail2 setValue:@"200" forKey:@"startTime"];
    [sleep_detail2 setValue:@"200" forKey:@"stopTime"];
    [sleep_detail2 setValue:@"200" forKey:@"settingstartTime"];
    [sleep_detail2 setValue:@"200" forKey:@"settingstopTime"];
    [sleep_detail2 setValue:@"Light Sleep" forKey:@"mode"];

    NSMutableDictionary * sleep_detail3 = [[NSMutableDictionary alloc] init];
    [sleep_detail3 setValue:@"200" forKey:@"startTime"];
    [sleep_detail3 setValue:@"200" forKey:@"stopTime"];
    [sleep_detail3 setValue:@"200" forKey:@"settingstartTime"];
    [sleep_detail3 setValue:@"200" forKey:@"settingstopTime"];
    [sleep_detail3 setValue:@"Deep Sleep" forKey:@"mode"];

    NSArray *sleep_detail_array = [NSArray arrayWithObjects: sleep_detail1,
                                   sleep_detail2,
                                   sleep_detail3,
                                   nil ];
    
    //sleep
    NSMutableDictionary * sleepData = [[NSMutableDictionary alloc] init];
    [sleepData setValue:@"200" forKey:@"startTime"];
    [sleepData setValue:@"200" forKey:@"stopTime"];
    [sleepData setValue:sleep_detail_array forKey:@"detail"];
    [sleepData setValue:@"200" forKey:@"calorie"];
    
    
    //activity.detail
    NSMutableDictionary * activity_detail1 = [[NSMutableDictionary alloc] init];
    [activity_detail1 setValue:@"200" forKey:@"startTime"];
    [activity_detail1 setValue:@"200" forKey:@"stopTime"];
    [activity_detail1 setValue:@"200" forKey:@"stepCnt"];
    [activity_detail1 setValue:@"200" forKey:@"distance"];
    [activity_detail1 setValue:@"Non-move" forKey:@"mode"];

    NSMutableDictionary * activity_detail2 = [[NSMutableDictionary alloc] init];
    [activity_detail2 setValue:@"200" forKey:@"startTime"];
    [activity_detail2 setValue:@"200" forKey:@"stopTime"];
    [activity_detail2 setValue:@"200" forKey:@"stepCnt"];
    [activity_detail2 setValue:@"200" forKey:@"distance"];
    [activity_detail2 setValue:@"Walking" forKey:@"mode"];

    NSMutableDictionary * activity_detail3 = [[NSMutableDictionary alloc] init];
    [activity_detail3 setValue:@"200" forKey:@"startTime"];
    [activity_detail3 setValue:@"200" forKey:@"stopTime"];
    [activity_detail3 setValue:@"200" forKey:@"stepCnt"];
    [activity_detail3 setValue:@"200" forKey:@"distance"];
    [activity_detail3 setValue:@"Fast Walking" forKey:@"mode"];

    NSMutableDictionary * activity_detail4 = [[NSMutableDictionary alloc] init];
    [activity_detail4 setValue:@"200" forKey:@"startTime"];
    [activity_detail4 setValue:@"200" forKey:@"stopTime"];
    [activity_detail4 setValue:@"200" forKey:@"stepCnt"];
    [activity_detail4 setValue:@"200" forKey:@"distance"];
    [activity_detail4 setValue:@"Running" forKey:@"mode"];

    NSArray *activity_detail_array = [NSArray arrayWithObjects: activity_detail1,
                                   activity_detail2,
                                   activity_detail3,
                                   activity_detail4,
                                   nil ];
    
    //activity
    NSMutableDictionary * activity = [[ NSMutableDictionary alloc] init];
    [activity setValue:@"200" forKey:@"statTime"];
    [activity setValue:@"200" forKey:@"stopTime"];
    [activity setValue:activity_detail_array forKey:@"detail"];
    [activity setValue:@"200" forKey:@"calorie"];
    
    //sync
    NSMutableDictionary * sync = [[ NSMutableDictionary alloc] init];
    [sync setValue:@"SEOUL" forKey:@"timezone"];
    [sync setValue:activity forKey:@"activity"];
    [sync setValue:sleepData forKey:@"sleep"];
    
    NSError *err;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sync options:NSJSONWritingPrettyPrinted error:&err];
    
    NSLog(@"JSON = %@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);


실제 디버깅 정보로 위에서 생성한 데이터가 json 문자열로 어떻게 생성되었는지 확인해보면
다음과 같다.
JSON = {
  "timezone" : "SEOUL",
  "activity" : {
    "stopTime" : "200",
    "detail" : [
      {
        "startTime" : "200",
        "stopTime" : "200",
        "stepCnt" : "200",
        "distance" : "200",
        "mode" : "Non-move"
      },
      {
        "startTime" : "200",
        "stopTime" : "200",
        "stepCnt" : "200",
        "distance" : "200",
        "mode" : "Walking"
      },
      {
        "startTime" : "200",
        "stopTime" : "200",
        "stepCnt" : "200",
        "distance" : "200",
        "mode" : "Fast Walking"
      },
      {
        "startTime" : "200",
        "stopTime" : "200",
        "stepCnt" : "200",
        "distance" : "200",
        "mode" : "Running"
      }
    ],
    "statTime" : "200",
    "calorie" : "200"
  },
  "sleep" : {
    "startTime" : "200",
    "stopTime" : "200",
    "detail" : [
      {
        "startTime" : "200",
        "stopTime" : "200",
        "settingstopTime" : "200",
        "settingstartTime" : "200",
        "mode" : "Awake"
      },
      {
        "startTime" : "200",
        "stopTime" : "200",
        "settingstopTime" : "200",
        "settingstartTime" : "200",
        "mode" : "Light Sleep"
      },
      {
        "startTime" : "200",
        "stopTime" : "200",
        "settingstopTime" : "200",
        "settingstartTime" : "200",
        "mode" : "Deep Sleep"
      }
    ],
    "calorie" : "200"
  }
}

2013년 4월 16일 화요일

iOS 프로그래밍 팁, jSON 객체를 주고 받는 클라이언트 개발

서버 <-----> iOS 클라이언트 관에 데이터 통신을 하는 앱 개발에 필요한 방법을 정리한다.



1. jSON 객체를 주고 받는다.
2. HTTP 프로토콜을 이용한다.
3. jSON 객체 string은 다음에 과정을 거친다.
jSON string --> base64Enc --> AES256Enc --> byte2Hex String --> HTTP 통신 --> 서버
서버 --> HTTP 통신 ---> hex2byte --> AES256Dec --> base64Dec --> JSON string


4. 필요한 모듈
이를 위해 필요한 것은 아래의 NSString 및 NSData 카테고리 클래스를 구해야 한다.



NSString+Base64.m / h

https://github.com/kyoshikawa/ZUtilities/blob/master/NSData%2BAES256.m

NSData+AES25.m / h

https://github.com/nicklockwood/Base64

NSData+Base64.m / h


5. 인크립트 디크립트 함수를 구현 하는 crypto클래스를 작성한다.
... 생략 ....



//string -> base64Enc -> aes256Enc -> byte2hex
- (NSString *) encryptString:(NSString *)textString {
    NSString * base64Enc = [self base64Encode:textString];
    NSData * aes256enc = [self encryptString:base64Enc withKey:[self generateKey]];
    return [self byteToHexString:aes256enc];
}

// hex2byte-> aes256Dec --> Base64Dec --> string
- (NSString *) decryptString:(NSString *)textString {
    NSData * data = [self hexToBytes:textString];
    NSString * aes256dec = [self decryptData:data withKey:[self generateKey]];
    return [self base64Decode:aes256dec];
}

... 생략 ...



6. jSON객체를 핸들링 하기 위한 모듈을 준비한다.
json 객체를 이용하기 위해서는 

http://superloopy.io/json-framework/

에서 jSON 모듈이 필요하다.


7. 서버에 요청 하기 위한 jSON객체 생성과 인크립트를 한다.


NSArray *keys = [NSArray arrayWithObjects:@"graduateNo", @"name", @"alumniName", nil];
    NSArray *objects = [NSArray arrayWithObjects:txtFieldNumber.text, txtFieldName.text, txtFiledAlumiName.text, nil];
    NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
    
    NSString *jsonString =[jsonDictionary JSONRepresentation];



위와 같이 key와 key값을 NSArray와 NSDictionary 를 이용하여 jsonString을 얻어 낼수 있다.

인크립트 메서드를 가지고 있는 crypto클래스를 이용해서 전송에 필요한 데이터를 구성한다.


8. 서버에 전송
NSMutableURLRequest,  NSURLConnection 을 이용해서 서버에 전송한다.

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
                                    [NSURL URLWithString:[NSString stringWithFormat: @"%@/api/xxxx.api",
                                                          SERVER_URL]]
                                                                cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
    
    [request addValue:@"application/x-www-from-urlencoded" forHTTPHeaderField:@"content-type"];
    [request setHTTPBody:jsonData];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d",[jsonData length]] forHTTPHeaderField:@"Content-Length"];
    
    NSURLConnection *connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
        
    if(connection) {
receiveData = [[NSMutableData alloc] init];
}

9. 서버로 부터 응답 처리


- (void)connection:(NSURLConnection *)connection didReceiveResponse:

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

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

응답에 관련된 메서드를 각각 구현한다.

서버에 응답 데이터에 대해서는
didReceiveResponse 에서 NSData 를 append 하고

connectionDidFinishLoading
에서 완성된 데이터를 crypto 클래스의 decryp 메서드를 이용해서 json 스트링으로 변환 한다.

마지막으로 JSONValue 를 통해서 NSDictionary로 변환 하여 
필요한 값을 valeuForKey로 얻어 낸다.