Apple is Apple

일일 회고

 

오늘은 개인 과제 수정과 선발대 과제 위주로 진행을 하였다.

 

개인과제는 디자인적인 면이나 코드 가독성적인 측면에서 수정을 진행하였다. 

이제 진행해볼 만한 것은 viewbinding -> databinding으로 리팩토링, depengency injection 적용해보기?(제에에에일 마지막) 정도일 것 같다.

 

선발대 과제는 뭔가 기능적으론 됐는데 코드가 흠?이라는 생각이 든다..ㅎㅎ 잘한건지 안한건지는 잘 모르겠다.ㅎㅎ


오늘의 키워드

  • IT 확장 세션
  • 개인 과제 

IT  직군 확장 세션

여러가지 직무

 

PM: 프로덕트(제품)를 관리하는 직무

PM은 모든 이해 관계자의 요구를 충족하는 제품을 만들기 위해 회사, 고객 및 제품 팀 간의 다리 역할을 함

 

SI: 새로운 시스템을 구축하는 업무

 

SM: 구축 되어 있는 시스템을 유지보수하는 직무

 

QA: 자사의 제품 기능을 검증하고 관리, 프로젝트 시작 부터 마무리까지 모든 과정을 함께 기획하고 올바른 방향을 찾고, 품질 저하요소를 발견하며 해당 프로젝트의 품질을 올리는데 주목적을 가짐

 

 

 

개인 과제

인터넷 연결 감지

네트워크 통신을 하는 프로그램 같은 경우, 인터넷의 상태가 매우 중요하다. 

데이터를 주고 받으려면 인터넷이 무조건 연결되어있어야하고, 되어있지 않으면 주고받는 작업 자체가 불가능 하기 때문이다. 또, 모종의 이유로 인터넷 연결이 불안정 할 수도 있는데, 프로그램에서는 다양한 상황에 대해 처리를 해주어야한다.

 

이번 과제에서는 모든 상황에 대해서는 처리를 하지 못하지만, 앱이 켜져있을 때에 인터넷 연결 감지를 해서 그때 마다, 다른 화면을 보여주는 기능을 추가해보았다.

class ConnectWatcher(
    context: Context
) : LiveData<Boolean>() {
    private val networkCallback by lazy {
        object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                postValue(true)
            }

            override fun onLost(network: Network) {
                postValue(false)
            }
        }
    }
    private val connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    override fun onActive() {
        connectivityManager.registerDefaultNetworkCallback(networkCallback)
    }

    override fun onInactive() {
        connectivityManager.unregisterNetworkCallback(networkCallback)
    }
}

먼저, 실시간으로 감지하기 위해서 LiveData를 상속받는 클래스를 만들어 주었다.

내부에서 네트워크 상태를 실시간으로 감지할 수 있는 NetworkCallback 객체를 만들어 주고 등록을 해주었다.

NetworkCallback객체에서는 onAvailable() (상태 연결), onLost() (상태 끊김) 메서드를 오버라이드 해주어 그 안에서 LiveData 값을 업데이트 시켜주었다.

private fun initNetworkStatus() = with(binding) {
        // 네트워크 상태 확인은 다른 프래그먼트를 만들 때, 확인 해야 할 필요가 있으므로 공유하는 뷰모델을 통해 연결
        ConnectWatcher(requireActivity()).observe(viewLifecycleOwner) { connection ->
            mainViewModel.setStatus(connection)
        }
        mainViewModel.networkStatus.observe(viewLifecycleOwner) { isAvailable ->
            when(isAvailable) {
                true -> {
                    networkNoticeTextView.isVisible = false
                    searchRecyclerView.isVisible = true
                    searchButton.isEnabled = true
                    reSearch()
                }
                false -> {
                    networkNoticeTextView.isVisible = true
                    searchRecyclerView.isVisible = false
                    searchButton.isEnabled = false
                }
            }
        }
    }

이제 실질적인 인터넷을 연결하는 검색 fragment에 위에서 만든 livedata를 연결시켜 주었다.

먼저, ConnetWatcher를 관찰하는 observer를 만들어 주고, connection 상태가 바뀔때 마다, ViewModel의 연결 status 상태를 업데이트 했다.

그리고 그 status을 관찰하는 observer를 만들어 주어, 상태가 true일 때는 정상 화면을 보여주고,  false (연결 끊김) 일 떄는 안내 메세지를 띄우도록 했다.

 

 

 

 

기능 수정

검색한 데이터를 시간 순으로 정렬할 필요가 있었다.

API 문서에는 DataTime  ([YYYY]-[MM]-[DD]T[hh]:[mm]:[ss].000+[tz]) 형식으로 받아온다고 했는데,  받았더니 이런 형태의 문자열로 데이터가 들어왔다.

날짜 순으로 정렬을 해주려면 이 문자열을 Date형식으로 다시 바꾸는 작업이 필요했다.

object StringExtension {
    fun String.dateToString() :String
            = this.split(".").first()

    private fun String.dateTimeToString(): String
            = this.split("T").joinToString(" ")

    fun String.stringToDate(): Date? {
        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.KOREAN)
        return sdf.parse(this.dateTimeToString())
    }
}

object DateExtension {

    fun Date.dateToString(): String {
        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.KOREAN)
        return sdf.format(this)
    }
}

String 확장함수를 만들어 Date형식으로 반환하고, ViewModel 쪽에서

list.sortedByDescending { it.dateTime }

위와 같이 시간 순으로 정렬해준 다음, 리사이클러뷰에 데이터를 제공하였다.

 

리사이클러뷰의 텍스트에도 시간 값을 넣어야 하는데, Date 값은 넣지 못하므로 Date.dateToString()이라는 함수를 만들어 다시 변환해서 텍스트에 넣어주었다.

profile

Apple is Apple

@mjjjjjj