๋ ์จ OpenAPI๋ฅผ ์ด์ฉํด์ Apple ๊ธฐ๋ณธ ๋ ์จ์ฑ ๋๋ Yahoo ๋ ์จ์ฑ๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ์ ์ ๊ตฌํํ๊ธฐ
ย
ย
- ๋ ์จ ์ ๋ณด
- ์ฅ์ ์ ์ฅ ๋ฆฌ์คํธ
- ์ฅ์ ๊ฒ์ ๋ฐ ์ถ๊ฐ
- ์จ๋ ๋จ์ ์ค์
- ์ฌ์ฉ์ ์ค์ ์ ์ฅ
์์น ๋ฆฌ์คํธ(ํ์ฌ ์์น + ์ ์ฅ๋ ์์น)์ ๋ ์จ๋ฅผ ๊ฐ๊ฐ ๊ฐ๋ก ์คํฌ๋กค๋ก ์ ํํ์ฌ ์กฐํ ๊ฐ๋ฅ
์ถ๊ฐํ๋ ์ฅ์ ๋ฆฌ์คํธ๋ฅผ ๋ณผ ์ ์๊ณ , ์ญ์ ํ ์ ์๋ค
์ํ๋ ์ฅ์๋ฅผ ๊ฒ์ํ์ฌ ์ถ๊ฐํ๊ณ , ๊ด๋ จ ๋ ์จ ์ ๋ณด๋ฅผ ๋ณผ ์ ์๋ค
์จ๋ ๋จ์๋ฅผ ์ญ์จ ํน์ ํ์จ๋ก ๋ณํํ์ฌ ๋ณผ ์ ์๋ค
๋ค์ ์ค์ ์ ์ ์ฅํ์ฌ ์ฑ์ ๋ค์ ์คํ์, ๊ธฐ์กด์ ์ค์ ๋๋ก ์คํ๋๋๋ก ํ๋ค
์ถ๊ฐํ ์ฅ์ | ์จ๋ ๋จ์ ์ค์ | ๋ง์ง๋ง์ผ๋ก ๋ณธ ํ์ด์ง |
---|---|---|
ย
ย
- ViewModel ์ view ๊ด๋ จ type ์ Observer ๋ฅผ ๋ฑ๋กํ ์ ์๋ ํ์
์ ๊ตฌํ
Observable
protocol- ViewModel - CurrentWeather, HourlyWeatherItem, DailyWetherItem, DetailWeather ๋์ data ๋ณํ์ ๋ํด observer ๋ฅผ ๋ฑ๋กํ ์ ์๋ค
- observer handler ์ ๊ด๋ จ view ๋ label text ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ํจ์๋ฅผ ๋ฑ๋ก
- view model ๋ณ๊ฒฝ์์ ํด๋น observer๊ฐ ์คํ๋์ด view ๋ ๊ฐ์ด ๊ทธ์ ๋ง๊ฒ ์ ๋ฐ์ดํธ ๋๋ค
ย
class / struct | ์ญํ |
---|---|
PageViewController |
LocationManager ์ฌ์ฉํด์ ๋ฐ์ ํ์ฌ์์น๋ฅผ ํฌํจํ์ฌ, ์ ์ฅ๋ ์์น์ ๋ ์จ๋ฅผ ๋ณด์ฌ์ค WeatherViewController ๋ฅผ ๋ณด์ฌ์ค๋ค |
WeatherViewController |
Location ๊ฐ์ฒด์ ํด๋นํ๋ ์์น ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค |
WeatherViewModel |
- OpenWeatherMapService ๋ฅผ ์ด์ฉํ์ฌ ์์น์ ๋ง๋ ๋ ์จ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค - WeatherBuilder ๊ฐ์ฒด๋ฅผ ํตํด ๊ฐ์ ธ์จ ์ ๋ณด๋ฅผ view ์ ํ์ํ ๋ฐ์ดํฐ ํ์ ๋ค๋ก ๋ง๋ ๋ค |
WeatherBuilder |
๋คํธ์ํน์ ํตํด ๋ฐ์์จ WeatherData ๊ฐ์ฒด๋ฅผ view model ์ ๊ฐ ํ์์ ๋ง๊ฒ ๊ฐ๊ณตํ๋ค |
LocationListViewController |
- ์ ์ฅ๋ ์์น๋ฅผ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค๋ค - ์ ์ฅ๋ ์์น๋ฅผ ์ญ์ ํ๋ค - ์จ๋ ๋จ์๋ฅผ ๋ฐ๊พผ๋ค - SearchViewController ๋ฅผ ๋ณด์ฌ์ค๋ค |
SearchViewController |
- ์ฌ์ฉ์ ๊ฒ์ ๋ฌธ์์ด์ ์ฌ์ฉํ์ฌ ์์น ์๋์์ฑ - ์ฌ์ฉ์๊ฐ ์ ํํ ์์น ์ ๋ณด(์ฅ์์ด๋ฆ, ์๋, ๊ฒฝ๋) ๋ฅผ LocationViewController delegate ํตํด ๋๊ธด๋ค |
Observable |
- ViewModel ์ ๊ฐ ๋ฐ์ดํฐ ํ์
์ observer ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํ generic type - WeatherViewModel ์์ observer ๋ฑ๋ก์ด ํ์ํ ์์ฑ์ ์ฌ์ฉ๋จ |
class / struct | ์ญํ |
---|---|
LocationManager |
CLLocationManager ์ฌ์ฉํ์ฌ ํ์ฌ ์์น ๊ฐ์ ธ์ค๊ธฐ |
OpenWeatherMapService |
- ๋คํธ์ํน ํตํ ๋ ์จ ์์ธก ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ - WeatherData ํ์
์ผ๋ก json decoding ํ๊ธฐ |
WeatherBuilder |
WeatherData โ WeatherViewModel ์ด ๊ฐ์ง ๊ฐ type์ผ๋ก ๋ฐ์ดํฐ ๊ฐ๊ณต |
WindDirection |
๋ฐ๋์ ๋ฐฉํฅ ๊ฐ(360๋ ๋ด)์ compass direction์ผ๋ก ๋ณํ |
DateConverter |
์ฃผ์ด์ง timezone ์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด๋ก ๋ ๋ ์ง๋ฅผ ๋ณํํด ์ฃผ๋ ์ญํ |
ย
ย
๊ด๋ จ ํ์ตํ ๋ด์ฉ- 1 ๊ด๋ จ ํ์ตํ ๋ด์ฉ- 2
view controller ๊ฐ ๋ฐ์ดํฐ๋ฅผ backward ๋ก ๋ฐ๊ธฐ ์ํด์, delegate protocol ์ ๊ตฌํํ์ฌ ์ฌ์ฉ
ย
LocationMagnager
class ๋ก ๊ตฌํ
CLLocationManager
๊ฐ์ฒด ์์ฑ- location ๋ฐ์ดํฐ์ ์ ํ๋ ์ค์ :
desiredAccuracy
property ์ค์ - ์ฌ์ฉ์์๊ฒ ์์น์ ๋ณด ์ฌ์ฉ ํ๊ฐ ๋ฐ๊ธฐ :
requestWhenInUseAuthorization()
method - ์์น ์์ฒญ์ด ๊ฐ๋ฅํ ํ๊ฐ ์ํ
CLAuthorizationStatus
:.authorizedWhenInUse
/.authorizedAlways
- ์์น ์์ฒญ:
requestLocation()
- ํด๋น method๋ ์ฆ๊ฐ return ํ๋ค
- ์์น ๊ฐ์ ์ป์ ํ, delegate ์
didUpdateLocation
method ๋ฅผ ํธ์ถํ๋ค
- Delegate method -
didUpdateLocation
ย
API JSON ๊ตฌ์กฐ (orange color : ๋ฐฐ์ด ๊ตฌ์กฐ)
- URLSession ํ์ตํ ๋ด์ฉ
- Codable :
Data
โWeatherData
๋ณํํ๊ธฐWeatherData
๋Codable
protocol ์ ์ค์JSONDecoder
์ฌ์ฉํ์ฌ ๋ณํ
ย
๋ฌธ์์ด๋ก ์์น๋ฅผ ์ ๊ณตํ๋ฉด ๊ทธ์ ๋ง๋ ์๋์์ฑ๋ comletion string list ๋ฅผ ์ ๊ณตํ๋ utility ๊ฐ์ฒด
-
๊ตฌํ ์๋ฆฌ
-
results
property :MKLocalSearchCompleter
์ ์๋์์ฑ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ์ป๋ ์์ฑMKLocalSearchCompletion
type- ์ง์ ์์ฑํ ์๋ ์๋ค. Completer ์ ์ํด์๋ง ์์ฑ๋๋ ๊ฐ์ฒด
-
completion ๋ ๋์ ์ง์ ๋ฐฉ๋ฒ
- ์์น ๋ฌธ์์ด, ์ง์ญ, ํํฐ ํ์ ๋ฑ์ ์ง์ ํ ์ ์๋ค.
- ๋์๋ช
๊ฒ์ :
queryFragment
property ์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ๋ ๋ฌธ์์ด ์ค์ - ํํฐ ํ์ : locationAndQueries / locationsOnly
-
delgate : search completion data ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๋ฉ์๋๊ฐ ์ ์๋จ
MKLocalSearchCompleterDelegate
completerDidUpdateResults()
๋ฉ์๋ : completer ๊ฐ ๊ฒ์ ์์ฑ ๋ฐฐ์ด์ ์ ๋ฐ์ดํธ ํ ๋ค ํธ์ถํ๋ ๋ฉ์๋.- ์ด ๋ฉ์๋ ์์ search ๊ฒฐ๊ณผ table view ๋ฅผ reload ํ๋๋ก ๊ตฌํํจ
ย
์ฌ์ฉ์ ์ค์ ํญ๋ชฉ
- ๋ง์ง๋ง์ผ๋ก ๋ณธ ๋ ์จ์ ์์น
- ์ฌ์ฉ์๊ฐ ์ ์ฅํ ์์น ๋ฆฌ์คํธ
- ์จ๋ ๋จ์ ์ ํ ์ ๋ณด
UserDefaults ์ ์ฌ์ฉ๋ key ๊ด๋ฆฌํ๋ struct DataKeys
ย
API ์์ ๋ฐ์์จ date & time (UTC ํ์ค) โ ๊ฐ ๋๋ผ๋ณ ์๊ฐ์ผ๋ก ๋ณํํ๊ธฐ
list.dt_text
string (utc ๋จ์ ์๊ฐ) โDate
๊ฐ์ฒด๋ก ๋ณํcity.timezone
: ํด๋น ๋์์ ์๊ฐ์ UTC๋ก๋ถํฐ ๋ณํํ๊ธฐ ์ํ ์ฐจ์ด๊ฐ. ๋จ์๋ ์ด- ๊ฐ ๋์์ ์๊ฐ =
list.dt_txt
๋ฅผ date๋ก ๋ณํํ ๊ฐ์ฒด +city.timezone
- ์ฐจ์ด๊ฐ ๋ํด์ฃผ๊ธฐ :
Date
-addingTimeInterval()
method ์ฌ์ฉ
ย
-
Singleton ์ผ๋ก ๊ตฌํํ ์ด์
- view controller ๋ฟ๋ง ์๋๋ผ ๋ ์จ ๊ด๋ จ๋ ๊ฑฐ์ ๋ชจ๋ data model ์์ ์จ๋์ ๊ด๋ จ๋ ๋ถ๋ถ์ด ๋ง์
- Singleton ํตํด์ ํ๋์ ์ธ์คํด์ค๋ก ์ฌ์ฉ์๊ฐ ์ค์ ํ ์จ๋ ๋จ์๋ฅผ ์ด์ฉํ๋๊ฒ ์ ์ ํ๋ค๊ณ ํ๋จ
-
TemperatureUnit
์shared
property ๋ก ๋จ์ ์ ๊ทผ ๊ฐ๋ฅ
ย
- ๋ฌธ์ ์ํฉ
- PageViewController ์์ swipe ์ ๋ฐ๋ฅธ ์ด์ /์ดํ ํ์ด์ง ์์ฒญ์๋ง๋ค ์๋กญ๊ฒ view controller instance (WeatherViewController) ๋ฅผ ์์ฑ
- ๋ฉ๋ชจ๋ฆฌ ๋ถํ๋ก ์ธํด ๊ฐ์๊ธฐ ๊บผ์ง๋ ํ์
- ํด๊ฒฐ ๋ฐฉ๋ฒ : View Controller Caching - NSCache
-
NSCache
- ์บ์ฑ์ ๊ตฌํํ ํด๋์ค๋ก mutable dictionary type ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค - key ๋ฅผ ํตํด ์บ์ฑํ ์ธ์คํด์ค ์ ๊ทผ ๊ฐ๋ฅ
- ๋๋ฐ์ด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ ๊ฒช์ ๋ ์ด ์บ์์ ์๋ ์ธ์คํด์ค์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์๋์ผ๋ก ํ์ํจ
var cachedWeatherViewControllers = NSCache<NSNumber, WeatherViewController>()
-
view controller๋ฅผ ํ๋ฒ ์์ฑํ ๋ค, caching ํ์ฌ ์ดํ์ view controller ์ ์์ฒญ์ด ์์ ๋, ์ด๋ฏธ ์ธ์คํด์ค๊ฐ ์๋ค๋ฉด ์ด๋ฅผ ๋ฐํํ๋ ๊ธฐ๋ฅ์ ๊ตฌํ
-
PageViewController ์์ ์บ์ฑํ WeatherViewController ์ธ์คํด์ค ๊ด๋ฆฌ
- Key: page index (
NSNumber
type) - Value:
WeatherViewController
instance
- Key: page index (
-
ย
- ๋ฌธ์ ์ํฉ
- ๋ง์ง๋ง์ผ๋ก ๋ ์จ ์ ๋ณด๋ฅผ ๋ณธ ์์น๋ฅผ ๋ฆฌ์คํธ์์ ์ญ์ ํ ๊ฒฝ์ฐ, ๋ค์ page view ๋ก ๋์๊ฐ์ ๋ page index ๊ฐ ๋ถ์ผ์น ํ๋ ํ์
- ํด๊ฒฐ ๋ฐฉ๋ฒ
- ์ญ์ ์ ์์น์ ๋ณด์ index ๊ฐ ๋ง์ง๋ง์ผ ๊ฒฝ์ฐ, ๋ง์ง๋ง์ผ๋ก ๋ณธ list index ๋ฅผ 0์ผ๋ก ์ค์ ํ๋ค.
ย
- ๋ฌธ์ ์ํฉ
- open weather map ์ 5์ผ / 3์๊ฐ api ์๋ 3์๊ฐ ๋ง๋ค์ ๋ ์จ ์์ธก ์ ๋ณด๋ ์์ง๋ง, ์ผ๋ณ ์์ธก ์ ๋ณด๋ ์๋ค.
- ๋ฐ๋ผ์, 3์๊ฐ ๋ง๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ผ๋ณ๋ก ๋ถ๋ฅํ๊ณ ์ด๋ฅผ ๋ค์ ๊ฐ๊ณตํ๋ ์ ์ฐจ๊ฐ ํ์
- ํด๊ฒฐ๋ฐฉ๋ฒ
WeatherData
โWeatherViewModel
์ด ๊ฐ์ง ๊ฐ model ๋ณ๋ก ๊ฐ๊ณตํ๋ ์ญํ ์ ๋ด๋นํ๋ ํด๋์ค ๊ตฌํWeatherBuilder
- 3์๊ฐ ๋ณ ๋ฐ์ดํฐ๋ฅผ ์ผ์๋ณ๋ก ๋ชจ์์, ์ผ์๋ณ ์ต๋/์ต์ ์จ๋๋ฅผ ๊ณ์ฐ โ
HourlyWeatherItem
์ผ๋ก ๋ง๋ค๊ธฐ
ย
ํ์ค ์ธํฐ๋ท ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ฌ ์๋ฒ์ url ๋ก ์ํตํ๋ ๋ฐฉ์
URL๋ก ํ์ธํ ์ ์๋ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ๋ฐฉ์์ URL Loading System ์ด๋ผ ํ๋ค.
resource loading ์ asynchronously (๋น๋๊ธฐ) ๋ก ์ํ๋๋ฏ๋ก, ์ ์ ์ ์ด๋ฒคํธ์ ์๋ตํ ์ ์๊ณ ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
Url ๋ก request ๋ฅผ ๋ณด๋ด๊ฑฐ๋ ๋ฐ๋ ์ผ์ ๋ด๋นํ๋ ๊ฐ์ฒด
- ์ค์ :
URLSessionConfiguration
- default
- ephemeral
- background
URLSession
instance ๋URLSessionTask
์ธ์คํด์ค๋ฅผ ํ๊ฐ ์ด์ ์์ฑํ์ฌ ์ฌ์ฉํ๋ค.- GET request ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์ผ :
URLSessionDataTask
- POST / PUT request ํตํด ํ์ผ์ ์
๋ก๋ ํ๋ ์ผ :
URLSessionUploadTask
- ์๊ฒฉ ์๋ฒ์์ ํ์ผ์ ๋ค์ด๋ก๋ ํด์ค๋ ์ผ :
URLSessionDownloadTask
- GET request ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์ผ :
- Task ์ํ
- suspend
- resume
- cancel
- URLSession ์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๋ ๋๊ฐ์ง ๋ฐฉ๋ฒ (๋น๋๊ธฐ์ ์ผ๋ก ์ํ๋๋ฏ๋ก, ๋๋จ์ ์๋ฆฌ๋ ๋ฐฉ๋ฒ)
- completion handler - task ๊ฐ ๋๋ ๋ ์คํ๋จ
- delegate ์ method ํธ์ถ
URL ์ ๊ตฌ์ฑํ๋ ์์๋ค์ ๊ตฌ์กฐ์ฒด๋ก ๋ํ๋
- queryItem property : URLQueryItem (name -value ์ง์ผ๋ก ๊ตฌ์ฑ๋์ด URL ์ query ๋ถ๋ถ์ ๋ด๋น)
- url property : ๊ตฌ์ฑ์์๋ค๋ก๋ถํฐ ์์ฑ๋ URL
๋ฐ์ดํฐ๋ฅผ URL ๋ก๋ถํฐ ๊ฐ์ ธ์ค๋ ค๋ฉด
- ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์ฃผ์ธ์ : request
- ์๋ต : reponse
func dataTask(with url: URL,
completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
shared
: singleton URLSession instance - ๊ฐ๋จํ request ์ฉ๋
let task = URLSession.shared.dataTask(with: url) {
// completion handler
}
-
Data : bytes or nil(error)
-
reponse: reponse ์ ๊ตฌํ์ฒด. HTTPURLReponse ๋ก ํ์ ์บ์คํ ๊ฐ๋ฅ
-
error: error ๋ฐ์์ ๊ฐ ์์. Nil ์ด๋ฉด ์ฑ๊ณต
-
๋คํธ์ํฌ ์ข ๋ฃ์ resume()
๋น๋๊ธฐ ์ํ์ ์ํ ๋, main queue(main flow) ๋ง๊ณ ๋ค๋ฅธ ์ํ queue ๋ก ์์ ์ ๋ณด๋ด๊ณ ์ถ์ ๋ ์ฌ์ฉ
main queue : system ์ด ์ ๊ณตํ๋ queue๋ก ๋ชจ๋ UI code ๊ฐ ์ํ๋์ด์ผ ํ๋ ๊ณณ
var items: [Item]?
DispatchQueue.main.async {
items = findItems(matching: "News")
}
// async ํด๋ก์ ธ๊ฐ ์คํ ์๋ฃ ๋ ๋, item ์ ๊ฐ์ด ํ ๋น ๋๋ค.
// ๋จ์ํ ์ ์ ์ธ๋ฌธ ์ง๋๊ฐ๋ค๊ณ ์คํ ์๋ฃ๋๊ฒ ์๋
network request ๊ฐ์ ๋ฌด๊ฑฐ์ด ์์ ์ ํ ๋๋ background queue ์์ ์คํ๋๋๊ฒ ์ฑ์ main ์์ ์คํ๋๋๊ฒ๋ณด๋ค ๊ถ์ฅ๋จ. - UI ๋ ๋ค๋ฅธ ์ผ์ ํ๋ ๋์ ๋ฌด๊ฑฐ์ด ์์ ๋ค์ ๋ค์์ ํ ์ ์์ผ๋ฏ๋ก
- view controller present ๊ด๊ณ
- presenting view controller : ๋(view controller) ๋ฅผ ๋์์ค, ๋ณด์ฌ์ค view controller
- presented view controller : ๋ด๊ฐ (view controller) present ํ๋, ๋์ด, ๋ณด์ฌ์ค view controller
- view controller ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ
- ๋ณด์ฌ์ค view controller ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ
present()
method - ๋ค์ ํ์ฌ์ view controller ๋ฅผ ๋ณด์ฌ์ค ์ด์ ์ view controller ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ค๋ฉด? delegate ํตํด ์ ๋ฌ~์ ๋ฌ
- ์ฝ๊ฒ ๋งํด์ ์๋ก์ด view controller ๋ฅผ instantiate ํด์ present ํ๊ธฐ ์ ์ ๋ด๊ฐ ๋ ๋ณด๋๋ค๋ ์ฐ๊ฒฐ์ delegate ๋ฅผ ํตํด ํ๋ ๊ฒ์ด๋ค
- ๊ทธ ์ฐ๊ฒฐ ๋ฐฉ์์ protocol ์ ํตํด์ ํด๋น protocol์ ๊ตฌํํ ํ์ ์ด๋ผ๋ฉด ๋๊ตฌ๋ delegate ๋ก ์ํตํ ์ ์๋ค๋ ๋ป์ด๋ค.
- ๋ณด์ฌ์ค view controller ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ
์ฑ์ data ๋ฅผ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ํ ํน์ ์ข ๋ฃ์์๋ ์์ด์ง์ง ์๊ณ persistent(์๊ตฌ) ๋ณด์กดํ ์ ์๋๋ก ํด์ฃผ๋ user default database
- key-value ํํ๋ก ์ ์ฅ๋๋ค. Key ๋ String ๋ง ๊ฐ๋ฅ
- ์ ์ฅ ๊ฐ๋ฅํ Value ํํ : NSData, NSString, NSNumber, NSArray, NSDictionary
- ํน์ฑ
- UserDefaults ํตํด ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ immutable
- plist extension ์ผ๋ก ์ ์ฅ๋จ
- app launch ๋ ๋, memory ์ ์ฌ๋ผ์จ๋ค.
- UserDefaults ๋ณ๊ฒฝ์ ์๋ฆผ์ ๋ฐ๊ณ ์ถ๋ค๋ฉด
- didChangeNotification ์ observer ๋ฅผ ๋ฑ๋กํ๋ฉด ๋๋ค.