티스토리 뷰
https://world-of-larooly.tistory.com/24
https://world-of-larooly.tistory.com/25
https://world-of-larooly.tistory.com/26
드디어 해당 부분을 정리해서 올렸네요.
다만 너무 잘라 올린 것 같아서 코드보기가 어려울것같더라고요 (머쓱)
그래서 코드만 따로 모아 올립니다.
설명은 위 링크들을 참고해주세요.
<ObjectMapper 클래스 선언>
import Foundation
import ObjectMapper
//MARK: getWeather - 날씨//ResponseGetFarmVilliage
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"]
}
}
}
<ViewController>
import Foundation
import UIKit
import Alamofire
import CoreLocation
import ObjectMapper
class WeatherBasicViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var gpsLbl: UILabel!
@IBOutlet weak var girdLbl: UILabel!
@IBOutlet weak var valueLbl: UILabel!
@IBOutlet weak var pcpLbl: UILabel!
@IBOutlet weak var popLbl: UILabel!
@IBOutlet weak var ptyLbl: UILabel!
@IBOutlet weak var rehLbl: UILabel!
@IBOutlet weak var skyLbl: UILabel!
@IBOutlet weak var snoLbl: UILabel!
@IBOutlet weak var tmnLbl: UILabel!
@IBOutlet weak var tmpLbl: UILabel!
@IBOutlet weak var tmxLbl: UILabel!
@IBOutlet weak var uuuLbl: UILabel!
@IBOutlet weak var vecLbl: UILabel!
@IBOutlet weak var vvvLbl: UILabel!
@IBOutlet weak var wavLbl: UILabel!
@IBOutlet weak var wsdLbl: UILabel!
let apiKey = "1단계 글을 참고해 주세요."
let apiUrl = "1단계 글을 참고해주세요./getVilageFcst?"
var mapManager : CLLocationManager!
var totalURL = ""
var nowTimeString = ""// 실제시간
var baseTimeString = ""// 측정 발표 시간
var fstTimeString = ""//예상 측정 시간
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
gpsLbl.text = "위도 , 경도 : \(getGpsLocation())"
girdLbl.text = "격자 : \(convertGPStoGRID(lat_X: getGpsLocation().0, lng_Y: getGpsLocation().1))"
getThreeTimesByString(getDate: Date.now)
totalURL = getWeatherApiUrl(time: Date.now, grid: convertGPStoGRID(lat_X: getGpsLocation().0, lng_Y: getGpsLocation().1))
weatherAlamofire()
}
@IBAction func clickButton(_ sender: Any) {
weatherAlamofire()
}
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
}
}
}
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 ?? ""))"
}
}
}
//MARK: - 여기까지는 기본 수식
func getWeatherApiUrl(time : Date , grid : (Int,Int))-> String{
var weatherUrl = apiUrl + "serviceKey=" + apiKey
weatherUrl += "&pageNo=1&numOfRows=1000&dataType=JSON&base_date="
weatherUrl += getCheckDate()
weatherUrl += "&base_time=\(getCheckTime())&nx=\(grid.0)&ny=\(grid.1)"
return weatherUrl
}
func getCheckTime() -> String {
return getIndexString(text: baseTimeString, startIndex: 8, endIndex: 12)
}
func getCheckDate() -> String {
return getIndexString(text: baseTimeString, startIndex: 0, endIndex: 8)
}
func getThreeTimesByString(getDate : Date){
let dateFormatter = DateFormatter()
// Set Date Format
dateFormatter.dateFormat = "YYYYMMddHHmm"
nowTimeString = dateFormatter.string(from: getDate)
fstTimeString = getIndexString(text: nowTimeString, startIndex: 0, endIndex: 10) + "00"
baseTimeString = getBaseTimeString()
}
func getIndexString(text : String,startIndex : Int , endIndex : Int) -> String {
let startIndex = text.index(text.startIndex, offsetBy: startIndex)// 사용자지정 시작인덱스
let endIndex = text.index(text.startIndex, offsetBy: endIndex)// 사용자지정 끝인덱스
return String(text[startIndex ..< endIndex])
}
func getBaseTimeString() -> String {
//ex) 20220517 -> 202205162300, 202205170200, 202205170500
let nowDateString = getIndexString(text: nowTimeString, startIndex: 0, endIndex: 8)
let upTimeLine = ["2300","0200","0500","0800","1100","1400","1700","2000"]
let yesterDayInt = Int(nowDateString)! - 1
let yesterDayString = String(yesterDayInt)
var timeArray : [Int] = []
for i in 0..<upTimeLine.count {
var newTimeElemt : String
if(i == 0){
newTimeElemt = yesterDayString + upTimeLine[i]
}else{
newTimeElemt = nowDateString + upTimeLine[i]
}
timeArray.append(Int(newTimeElemt)!)
}
let nowTimeInt = Int(nowTimeString)!
for i in 0..<timeArray.count {
if(timeArray[i] > nowTimeInt){
if(i > 0){ // 시간차이가 얼마 안날때 i> 0
if(nowTimeInt - timeArray[i-1] < 100){
return String( timeArray[i-2] )
}else{
return String( timeArray[i-1] )
}
}else{
return String( timeArray[i-1] )
}
}
}
return String( nowTimeInt )
}
func getGpsLocation() -> (Double,Double){
mapManager = CLLocationManager()
mapManager.delegate = self
mapManager.requestWhenInUseAuthorization()
mapManager.desiredAccuracy = kCLLocationAccuracyBest
mapManager.startUpdatingLocation()
let coor = mapManager.location?.coordinate
var lat = coor?.latitude
var long = coor?.longitude
return (lat,long) as! (Double, Double)
}
func convertGPStoGRID( lat_X: Double, lng_Y: Double) -> (Int,Int) {
let RE = 6371.00877 // 지구 반경(km)
let GRID = 5.0 // 격자 간격(km)
let SLAT1 = 30.0 // 투영 위도1(degree)
let SLAT2 = 60.0 // 투영 위도2(degree)
let OLON = 126.0 // 기준점 경도(degree)
let OLAT = 38.0 // 기준점 위도(degree)
let XO:Double = 43 // 기준점 X좌표(GRID)
let YO:Double = 136 // 기1준점 Y좌표(GRID)
let DEGRAD = Double.pi / 180.0
let re = RE / GRID
let slat1 = SLAT1 * DEGRAD
let slat2 = SLAT2 * DEGRAD
let olon = OLON * DEGRAD
let olat = OLAT * DEGRAD
var sn = tan(Double.pi * 0.25 + slat2 * 0.5) / tan(Double.pi * 0.25 + slat1 * 0.5)
sn = log(cos(slat1) / cos(slat2)) / log(sn)
var sf = tan(Double.pi * 0.25 + slat1 * 0.5)
sf = pow(sf, sn) * cos(slat1) / sn
var ro = tan(Double.pi * 0.25 + olat * 0.5)
ro = re * sf / pow(ro, sn)
var ra = tan(Double.pi * 0.25 + (lat_X) * DEGRAD * 0.5)
ra = re * sf / pow(ra, sn)
var theta = lng_Y * DEGRAD - olon
if theta > Double.pi {
theta -= 2.0 * Double.pi
}
if theta < -Double.pi {
theta += 2.0 * Double.pi
}
theta *= sn
let x = Int(floor(ra * sin(theta) + XO + 0.5))
let y = Int(floor(ro - ra * cos(theta) + YO + 0.5))
return (x,y)
}
}
음... 통으로 올리고 보니 앞의 글에 수정할 부분들이 조금씩 보이네요;;;
조금씩 다듬으러 가야겠네요;;
그래도 이 코드가 누군가에게 도움이 된다면 좋겠네요.
그럼 오늘도 파이팅입니다.
'iOS개발 > Swift 통신' 카테고리의 다른 글
Swift ObjectMapper 사용해보기 (0) | 2022.12.26 |
---|---|
Swift FCM 연결용 AppDelegate (Only Code) (0) | 2022.12.02 |
Swift 날씨 api 연결해보기 3단계(완) (0) | 2022.12.01 |
Swift 날씨 api 연결해보기 2단계 (0) | 2022.12.01 |
Swift 날씨 api 연결해보기 1단계 (0) | 2022.12.01 |
댓글