티스토리 뷰

https://world-of-larooly.tistory.com/24

 

Swift 날씨 api 연결해보기 1단계

이번에는 사용자의 지역에 따른 날씨를 가져올 일이 생겨서 한번 만들게 되었는데 저처럼 "이걸 어떻게 해야 하지?" 하시는 분들을 위해 올려봅니다. 참고로 이번 포스트는 따라하시기 전에 준

world-of-larooly.tistory.com

https://world-of-larooly.tistory.com/25

 

Swift 날씨 api 연결해보기 2단계

https://world-of-larooly.tistory.com/24 Swift 날씨 api 연결해보기 1단계 이번에는 사용자의 지역에 따른 날씨를 가져올 일이 생겨서 한번 만들게 되었는데 저처럼 "이걸 어떻게 해야 하지?" 하시는 분들을

world-of-larooly.tistory.com

자 드디어 3단계 에요 이후에 순수 코드만 올려놓겠습니다. 

(사실 코드만 보면 생각보다 짧은데 설명할 내용이 많네요;;;)

 

2단계까지 오셨다면 JSON까지는 가져오셨을거라 생각하고 진행하겠습니다. 

사실 이후 단계부터는 다른 방법을 사용하셔도 무관합니다. 

 

그럼 마지막 단계 시작하도록 하죠.

참고로 1단계에서 이미 이야기된대로 

ObjectMapper 를 사용할껍니다. 

(ObjectMapper는 JSON 을 쉽게 변수화 하거나 변수를 JSON으로 만들기 편하게 해주는 기능을 가지고 있어요)

 

그러면 일단 받는 부분을 알맞게 만들어야겠죠? 

저의 경우에는 아래 처럼 미리 만들어 두었습니다. 

import Foundation
import ObjectMapper

//MARK: getWeather - 날씨
class ResponseGetWeather : Mappable{
    var response : Response? = nil
    
    required init?(map: Map) {
    }
    func mapping(map: Map) {
        self.response <- map["response"]
    }
    
    class Response: Mappable {
        var header: Header?
        var body: Body?

        required init?(map: Map) {
            
        }
        
        func mapping(map: Map) {
            self.header <- map["header"]
            self.body <- map["body"]
        }
    }
    //MARK: - head
    class Header: Mappable {
        var resultCode, resultMsg: String?
        required init?(map: Map) {
            
        }
        func mapping(map: Map) {
            self.resultCode <- map["resultCode"]
            self.resultMsg <- map["resultMsg"]
        }
    }
    // MARK: - Body
    class Body: Mappable {
        var dataType: String?
        var items: Items?
        var pageNo, numOfRows, totalCount: Int?

        required init?(map: Map) {
            
        }
        
        func mapping(map: Map) {
            self.dataType <- map["dataType"]
            self.items <- map["items"]
            self.pageNo <- map["pageNo"]
            self.numOfRows <- map["numOfRows"]
            self.totalCount <- map["totalCount"]
        }
    }

    // MARK: - Items
    class Items: Mappable {
        var item: [Item]?
        required init?(map: Map) {
            
        }
        
        func mapping(map: Map) {
            self.item <- map["item"]
        }
    }

    // MARK: - Item
    class Item: Mappable {
        var baseDate, baseTime: String?
        var category: String?
        var fcstDate, fcstTime, fcstValue: String?
        var nx, ny: Int?

        required init?(map: Map) {
            
        }
        
        func mapping(map: Map) {
            self.baseDate <- map["baseDate"]
            self.baseTime <- map["baseTime"]
            self.category <- map["category"]
            self.fcstDate <- map["fcstDate"]
            self.fcstTime <- map["fcstTime"]
            self.fcstValue <- map["fcstValue"]
            self.nx <- map["nx"]
            self.ny <- map["ny"]
        }
    }
}

사용법은 간단합니다. 

 

1. 2단계 마지막에 있던 부분을 아래처럼 수정합니다. 

func weatherAlamofire(){
        print(totalURL)
        AF.request(totalURL).responseData{ response in
            switch response.result {
                case .success(let data):
                    do {
                        print(response.data)
                        let asJSON = try JSONSerialization.jsonObject(with: data)
                        
                        let sample = Mapper<ResponseGetWeather>().map(JSONObject: asJSON)
                        if(sample != nil){
                            self.setAllInfo(item: self.filterTodayWeather(allItems: sample!.response!.body!.items!.item)!)
                        }
                       
                    } catch {
                        print("Error while decoding response: \(error) from: \(String(data: data, encoding: .utf8))")
                    }
                case .failure(let error):
                    print("Error get Value from Server")
                    break
                    // Handle as previously error
                }
        }
    }

2. 오늘 날짜의 최신 기상 예보를 가져오도록 조절해주는 함수를 넣습니다. 

- 실제로 값을 보면 각 시간대별 예상 기상 정보가 다 나오기 때문에 한번 걸러줘야합니다.

- 저의 경우 가능하면 최신값을 가져오도록 조절해놨습니다. 

    func filterTodayWeather(allItems : [ResponseGetWeather.Item]?) -> [ResponseGetWeather.Item]? {
        let baseDate = self.getIndexString(text: self.baseTimeString, startIndex: 0, endIndex: 8)
        let baseTime = self.getIndexString(text: self.baseTimeString, startIndex: 8, endIndex: 12)
        let fstDate = self.getIndexString(text: self.fstTimeString, startIndex: 0, endIndex: 8)
        let fstTime = self.getIndexString(text: self.fstTimeString, startIndex: 8, endIndex: 12)
        
        if(allItems == nil){
            return nil
        }
        var resultArray: [ResponseGetWeather.Item] = []
        for i in allItems! {
            if(i.baseDate == baseDate && i.baseTime == baseTime && i.fcstDate == fstDate && i.fcstTime == fstTime ){
                resultArray.append(i)
            }
        }
        return resultArray
    }
     func setAllInfo(item : [ResponseGetWeather.Item]){
        for i in item {
            if(i.category == "PCP"){
                pcpLbl.text =  "강수량(PCP) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "POP"){
                popLbl.text =  "강수확률(POP) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "PTY"){
                ptyLbl.text =  "강수형태(PTY) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "REH"){
                rehLbl.text =  "습도(REH) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "SKY"){
                skyLbl.text =  "구름양(SKY) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "SNO"){
                snoLbl.text =  "적설량(SNO) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "TMN"){
                tmnLbl.text =  "아침 최저기온(TMN) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "TMP"){
                tmpLbl.text =  "기온(TMP) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "TMX"){
                tmxLbl.text =  "낮 최고기온(TMX) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "UUU"){
                uuuLbl.text =  "동서바람성분(UUU) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "VEC"){
                vecLbl.text =  "풍향(VEC) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "VVV"){
                vvvLbl.text =  "남북바람성분(VVV) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "WAV"){
                wavLbl.text =  "파고(WAV) : \(i.fcstValue ?? ""))"
            }
            if(i.category == "WSD"){
                wsdLbl.text =  "풍속(WSD) : \(i.fcstValue ?? ""))"
            }
        }
    }

* 참고로 각 카테고리 별 의미는 

https://world-of-larooly.tistory.com/21

 

날씨 API 받아온 데이터 의미 알기

안녕하세요. 이번에는 날씨 API 에 대한 이야기를 해볼까합니다. 참고로 이 글은 연결하는 방법이 아니라 받아온 데이터가 뭔 의미인지 알기위해 작성되었습니다. 저번에 한번 연결해서 데이터

world-of-larooly.tistory.com

해당 글을 참고해주시면 편하실 겁니다. 

 

이런식으로 화면에 뿌려주시면 

화면에 대략적으로 뿌리면 이렇게 보입니다.

물론 값을 못가져오는 경우가 있을 수 있습니다!!!

사진에 빈 공간이 보이시는 이유가 그겁니다.

 

또한 가져오다가 인터넷 문제로도 못가져올수있으니 그 점 유의해 주세요! 

(즉 100% 항상 안정적으로 가져오는 것은 아니라는 의미입니다.)

 

아무튼 저의 경우는 이렇게 코드를 작성했는데 

저처럼 어떻게 해야할지 방향을 못잡으시는 분들이 계실것같아 올려봅니다. 

(다음 포스트에 전체 코드만 따로 올려 보도록 하겠습니다.)

 

도움이 되셨기를 바라며 

오늘도 파이팅입니다.

댓글