일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Clean Code
- Human interface guide
- 애니메이션
- rxswift
- Observable
- swift documentation
- map
- clean architecture
- UICollectionView
- 리펙터링
- SWIFT
- 리팩토링
- uiscrollview
- ios
- tableView
- combine
- swiftUI
- UITextView
- MVVM
- 리펙토링
- Xcode
- 클린 코드
- 스위프트
- Protocol
- uitableview
- Refactoring
- HIG
- ribs
- RxCocoa
- collectionview
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 2. 서버 - RESTful API 실습 (Foundation framework사용) 본문
[iOS - swift] 2. 서버 - RESTful API 실습 (Foundation framework사용)
jake-kim 2020. 4. 24. 02:08* 통신은 주로 Alamofire프레임워크를 사용하지만, 기본기를 위해서 Foundation 프레임워크로 구현 해보기
1. ATS설정과 API문서
1) HTTP통신인 경우 ATS(App Transport Security)설정
- 허용되는 사이트를 설정
App Transport Security Settings 추가 -> 하위 탭에서 Allow Arbitrary Loads 추가 -> YES로 변경
- 특정 사이트만 허용하는 방법
(1)App Transport Security Settings -> Exception Domains 하위 항목에 아이템 생성 후 Dictionary로 설정
(2)New Item이라고 있던 곳을 "www"나 서브 도메인 제외하고 주소를 입력
(3) 하위 항목에 다음 세 가지 아이템 추가 후, 옵션이름을 적고 Boolean타입으로 변환 -> YES로 설정
NSExceptionAllowsInsecureHTTP : 해당 도메인에 대해 HTTP접속을 허용할지 여부 결정
NSExceptionAllowsInsecureHTTPLoads : 해당 도메인에 대한 HTTP통신을 허용할지 여부 결정
NSIncludeSubdomains : ATS구성이 입력한 도메인의 서브 도메인에도 적용 (기본값은 NO)
2) API문서의 형태
항목 | 값 |
Description | 서버로 부터 현재 시간을 가져오는 것 |
URL | http://swiftapi.rubypaper.co.kr:2029/practice/currentTime |
Method | GET |
REQ | 없음 |
RES | 날짜 형태의 문자열(예시, 2020-04-24 12:18:48) |
(위 API문서를 읽고 전체적인 내용 파악)
3) 간단한 API테스트 도구 : "포스트맨(Postman)"
postman 다운 -> 가입 -> open -> '+'버튼을 누르면 밑과 같은 화면 등장
2. RESTful API
1) GET 방식
항목 | 값 |
Description | 서버로 부터 현재 시간을 가져오는 것 |
URL | http://swiftapi.rubypaper.co.kr:2029/practice/currentTime |
Method | GET |
REQ | 없음 |
RES | 날짜 형태의 문자열(예시, 2020-04-24 12:18:48) |
1
2
3
4
5
6
7
8
9
10
11
12
|
do {
// METHOD : GET
// API 호출
let response = try String(contentsOf: url!)
print(response) // 2020-04-24 00:39:01
} catch let error as NSError {
print(error.localizedDescription)
}
|
* API호출 방법 (반환 타입 설정)
(1) Base64인코딩 형식 : let response = try Data(contentsOf: url!)
* Base64 인코딩 : binary data -> ASCII format
이미지 데이터에 많이 사용 (binary데이터는 이동하다가 서버에서 1byte로 묶여서 데이터에 손실이 올 수 있기 때문)
(2) 문자열 반환 : let response = try String(contentsOf: url!)
(3) UTF-8인코딩 : let response = try NSString(contentsOf: url!, encoding: String.Encoding.utf8.rawValue)
* 한글과 같은 2byte를 사용하는 언어를 utf-8로 인코딩
2) POST 방식
(String 방식)
항목 | 값 |
Description | 클라이언트가 보낸 요청을 그대로 JSON형식으로 변경하여 응답 |
URL | http://swiftapi.rubypaper.co.kr:2029/practice/echo |
Method | POST |
Content Type | x-www-form-urlencoded |
REQ | 사용자 정의 형식 |
RES |
JSON 객체 형식 result : 성공 시 "SUCCESS", 실패 시 "FAIL" 기타 : 사용자 요청 내용을 그대로 회신 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
@IBAction func post(_ sender: Any) {
// 바디에 넣을 데이터 생성
let bodyParam = "userId=\(self.id.text!)&name=\(self.name.text!)"
let body = bodyParam.data(using: .utf8)
// URL 객체 정의
// 1) REQ - 라인 설정
var req = URLRequest(url: url!)
req.httpMethod = "POST"
// 2) REQ - 헤더 설정
req.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") // POST
req.setValue(String(body!.count), forHTTPHeaderField: "Content-Length") // 서버에 길이 알림
// 3) REQ - 바디 설정
req.httpBody = body
// 서버에 전송
URLSession.shared.dataTask(with: req) {(data, response, error) in
// error 체크
if let e = error {
print(e.localizedDescription)
return
}
print("response=\(response)")
DispatchQueue.main.async {
do{
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
guard let jsonObj = json else {return}
let result = jsonObj["result"] as? String
let id = jsonObj["userId"] as? String
let name = jsonObj["name"] as? String
if result == "SUCCESS" {
// data 확인
print("결과==>\(String(data: data!, encoding: .utf8)!)")
// responseView는 @IBOulet변수
self.responseView.text = "아이디 = \(String(id!))\n"
+ "이름 = \(String(name!))\n"
}
} catch let e as NSError {print(e.localizedDescription)}
}
}.resume() // resume()을 해야 전송이 됨 : URLSession.shared.dataTask(...)객체
}
|
cf) JSON형식으로 통신하려면?
API문서에서 Content Type이 application/json명시되어 있다면,
- 위 코드에서 4번줄 bodyParam을 딕셔너리 형태로 구현 (let bodyParam = ["userId" : id, "name" : name] )
- 헤더 설정에서 15번줄을 "application/json"타입으로 수정
- 5번줄 body는 JSONSerialization.data(withJSONObject:bodyParam, options:[])
*소스 코드 및 API출처 : 루비페이퍼, 꼼꼼한 재은씨의 스위프트 실전편
'iOS 실전 (swift) > 서버' 카테고리의 다른 글
[iOS - swift] 6. 서버 - OAuth, Key Chain, 로그인 관리 토큰 (0) | 2020.04.25 |
---|---|
[iOS - swift] 5. 서버 - Indicator View (버퍼링 표현) (0) | 2020.04.25 |
[iOS - swift] 4. 서버 - Alamofire를 이용한 회원가입 요청, 응답 (0) | 2020.04.24 |
[iOS - swift] 3. 서버 - Alamofire (RESTful API) (0) | 2020.04.24 |
[iOS - swift] 1. 서버 - HTTP, RESTful API (0) | 2020.04.23 |