[돌아보기] Apple 기본 날씨앱 클론코딩을 끝내며..

김혜수·2021년 8월 20일
1

내 활동 모음

목록 보기
2/3
post-thumbnail

날씨 클론코딩 스터디인 '무더'.. 브랜딩을 한게 엊그제 같은데, 벌써 4주의 시간이 지났다.
일단 우리의 계획은 다음과 같았다.

4주간 애플 기본날씨앱 클론 코딩을 하면서 새로 알게된점이 무엇이 있는지 적어보려고 한다
설명을 적을건 아니고 간단하게 한두줄 정도만! 그냥 일기같은 글,, 임다..

1. 현재위치 받아오기

CLLocationManager 를 통해 현재 위치의 위도, 경도를 받아왔다. (정말.. 정확하게 나오더라..)

import CoreLocation


var locationManager: CLLocationManager = CLLocationManager()
var latitude: Double? // 위도
var longitude: Double?// 경도
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
        
if CLLocationManager.locationServicesEnabled() {
	locationManager.startUpdatingLocation()
            
	/// 현재 위도와 경도 가져오기
	let location = locationManager.location?.coordinate
    
	/// 가져온 현재 위도와 경도 저장
	latitude = location?.latitude!
	longitude = location?.longitude!
          
	// ...
}   

info.plist에서 앱 사용중 위치 가져오기 관련 내용도 추가해줍니다.

근데 시뮬에서는 지역 받아오기가 안된다,, 현재 지역 받으려면 무조건 실기기에서 해야함! 시뮬에서 하니까 무슨 샌프란시스코 나오더라,,

2. CLGeocoder 를 이용해 위도, 경도 -> 지역 주소 변환하기

현재 위도, 경도를 가져오면 그 정보를 가지고 주소로 변환해서 화면에 보여줘야 했기에, CLGeocoder를 이용해 주소로 변환해 주었다. 여러 속성들이 있는데 .locality 로 해주면 전체 주소가 아니라 지역 이름만 나오게 할 수 있다.! (ex. 용산구 청파동 -> '용산구'만 나오도록)

3. Moya 라이브러리를 이용한 서버통신

날씨 클론코딩 전까지 주변에서 Moya에 대한 이야기를 굉장히 많이 들었기에,, 이번에 처음으로 Moya 라이브러리를 사용하여 서버통신을 해보았다. Moya는 Alamofire를 사용하기 좋게 한번 더 감싼 라이브러리인것 같은데 확실히 눈에 잘 보이는 방식으로 필요한 모든 것을 설정할 수 있어서 편했던 것 같다. 앞으로 자주 애용할 것 같다. (하지만 다음번엔 URLSession을 이용한 서버통신에 도전해보기로,,)

4. mapkit 사용해보기

검색뷰에서 지역들을 가져오기 위해 Swift에 기본으로 들어있는 mapkit을 사용해보았다.

 guard let placeMark = response?.mapItems[0].placemark else {
                return
            }
            
            
print("가져온 주소", placeMark.coordinate)
print("나라이름", placeMark.countryCode!)
print("지역이름", placeMark.locality ?? "없어요..없어..")
print("위도", placeMark.coordinate.latitude)
print("경도", placeMark.coordinate.longitude)

요렇게 다양한 정보들을 가져올 수 있다!

5. Lottie 사용

로티를 사용해본건 iOS 세미나때 뿐이었는데, 직접 로티 파일을 다운받고 프로젝트에 적용해본건 처음이었다. 확실히 그냥 배경만 있는 것보다 귀여운..로티가 들어가니까 훨씬 맘에 들었다.
새롭게 검색해서 알게된 로티무한재생 방법은 아래와 같다.

animationView.loopMode = .loop

6. CAGradientLayer, mask

나는 테이블뷰의 section을 이용해서 Sticky Header를 구현했는데, 테이블뷰 전체가 투명한 애플 날씨앱의 (킹받는..) 특징 때문에 문제가 생겼다. 바로 tableview를 스크롤해서 위로 올리면 Section 뒤에 row가 올라가면서 내용이 다 비쳐보였다는 것..!
이 문제를 아무리 찾아도 해결할 수 없어서 상단은 UIView + 하단은 TableView 조합도 써봤지만, 애플 날씨앱은 화면 어느 위치에서나 스크롤이 되는 앱이었기 때문에.. 이렇게 할 수가 없었다. (UIView + UITableview를 쓰면 UIView부분은 스크롤이 안되기 때문..)

그래서 일단 넘기고 다른거부터 구현하자! 했는데 예지윤언니가 해답을 찾아왔다. 바로 Mask를 이용해 섹션 뒷부분으로 올라가는 부분을 안보이게 해주는 것.. ! 아직 Mask에 대한 내용은 모르는 부분이 많아서 다시 공부해서 정리해보려고 한다. 이부분을 구현하면서 스터디의 집단지성과 위대함을.. 다시한번 더 깨달았다

7. OpenAPI 를 사용해보았다

처음으로 Open API 를 사용해서 구현을 해보았다. 우리는 날씨에 대한 정보를 받아와야 했기에 OpenWeatherMap API 의 One Call 을 사용했다.
개인키도 처음 발급받아보고,,
baseURL과 개인키는 유출되지 않도록 gitignore에 올린 파일(GeneralAPI.swift)에 static으로 선언한 후, 필요할때마다 GeneralAPI.baseURL 혹은 GerneralAPI.appid 로 불러와서 사용했다.

https://openweathermap.org/api

8. page controller

평소 앱에서 page controller를 많이 봤던 것 같은데, 직접 사용해본건 이번이 처음이다! 나는 처음엔 커스텀 탭바 했던 것처럼 직접해줘야되는 건줄 알았는데 기본적으로 제공하는 것이었더라..
암튼 pageController의 사용법은 그리 어렵지 않았다!

  • iBAction을 통해 pageController의 변화를 감지할 수 있고
@IBAction func pageChanged(_ sender: Any) {
     
        UIView.animate(withDuration: 0.3){
            self.scrollview.contentOffset.x = UIScreen.main.bounds.width * CGFloat(self.pagecontrol.currentPage)
        }
        
  • currentPage를 통해 현재페이지를 설정할 수 있다.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
        pagecontrol.currentPage = Int(floor(scrollview.contentOffset.x / UIScreen.main.bounds.width))
    }
  • setIndicatorImage를 이용해 동그라미였던 인디케이터 이미지를 바꿔줄 수 있다. (날씨앱에서는 0번째 자리에 있는 이미지만 화살표 이미지라 아래와 같이 설정했다.)
 pagecontrol.setIndicatorImage(UIImage(systemName: "location.fill"), forPage: 0)

9. 현지 시간 설정, timeZone

나라마다 시간이 다르기에 timeZone을 이용하여 각각 다른 시간을 설정해주었다. (timeZone은 API에서 가져왔다.)

아래와 같은 String Extension을 만들어 사용해주었다.

/// 현재시간
extension String {
    func nowTime(_ format: String, _ timezone: Int) -> String {
        let date = Date()
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.locale = Locale(identifier: "ko_KR")
        dateFormatter.timeZone = TimeZone(secondsFromGMT: timezone)
        return dateFormatter.string(from: date as Date)
    }
}

마지막 한마디..

힘들었지만 돌아보니 새로 해본것도 많고 뿌듯하다~!
하다보니 비동기 처리, RxSwift, MVVM 필요성을 좀 많이 느껴서
이제 슬슬 이 내용에 대해 공부해보려고 한다. 빠이팅.!
일단 클론코딩은 10일간 쉬고.. 잠시 재충전의 시간을 가지기로..
다음 클코 기대된다

글고.. 사랑하는 무더위들 덕분에 끝까지 할 수 있었던 것 같아서 넘 감사하고..
스터디의 위대함 (집단지성..중간공유..짜릿해)을 몸소느꼈던 4주였다~~!

profile
iOS를 좋아하는 사람

4개의 댓글

comment-user-thumbnail
2021년 8월 21일

수고했다 김셰후 !

답글 달기
comment-user-thumbnail
2022년 2월 18일

혹시 Lottie 사용하실 때 배경화면 어디서 구하셨는지 알 수 있을까요?

1개의 답글