<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>일해라토토</title>
    <link>https://develop-toto.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 11 Oct 2026 20:13:57 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>일해라토토</managingEditor>
    <image>
      <title>일해라토토</title>
      <url>https://tistory1.daumcdn.net/tistory/5947993/attach/1509aa76a1f5407691f8bbb21c41c2ec</url>
      <link>https://develop-toto.tistory.com</link>
    </image>
    <item>
      <title>신입 iOS 개발자 1년간의 회고</title>
      <link>https://develop-toto.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느덧 iOS 개발자로 1년이 되었더라구요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 작성하려던 생각도 있었지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마침 추석이라 시간이 많기도 하고, 사수분께서 회고 작성해보라고 하신김에 해볼까 해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신입 개발자로서 느꼈던 점이나 앞으로의 목표에 대해 작성해볼까 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1년동안 어떤 개발을 했는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년동안 뭔가 열심히는 한 것 같은데 무슨 업무를 했는지 갑자기 작성하려니 잘 떠오르지는 않네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지라 티켓 같은 유지보수 업무를 하기도 했지만, 제가 담당해서 개발 진행했던 부분을 정리해보려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 내용이라 간략하게만 적어보자면 아래 내용들 개발한 것 같아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;- Chart 라이브러리 이용한 그래프 기능 개발&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-Google Analytics4 Log 추가 및 수정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-회사 자체 event Log 수집 대응 개발&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;- 커뮤니티 신규 개발&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;- 이벤트 신규 기능 개발&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;어렵거나 힘들었던 점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨처음에는 회사 내 iOS 개발 환경 및 아키텍처에 익숙해지려 노력했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 서비스는 &lt;b&gt;MVVM, RxSwift&lt;/b&gt; 를 위주로 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신입 개발자인 저에게는 코드가 너무 어렵게 느껴지더라구요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC패턴 정도만 공부해봤고, MVVM 패턴은 처음이라 어떻게 사용하는지 이해하는데 시간이 꽤 걸렸습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 아직도 view 에서 viewModel에 있는 output 들을 바로 접근하는 실수를 하곤 하는데 이건 얼른 고치려고 노력하고 있습니다..ㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RxSwift는 아직도 정확히 제대로 알고 사용하고 있지 않은 느낌이에요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 코드를 참고해서 구현은 할 수 있지만, 가끔씩 개발하다보면 오류 해결하는데 시간이 오래 걸리곤 하더라구요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;deinit, dispose, dataSource 같은 것들을 신경쓰고 개발해야 하는데 아직도 공부가 필요한 부분입니다..ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;많이 성장했다고 느끼는 부분&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 1년동안 많이 익숙해지고 배웠다고 생각한 부분은 UI 개발인 것 같아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초반에는 autoLayout 도 제대로 설정 못해서 버벅였던 기억이 많네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 처음 팀에 합류했을 때 UI 관련 convention이 따로 존재하지 않아, &amp;nbsp;xib 및 code로 작성되어 있는 기존소스를 파악하려면 둘다 할 줄 알아야 해서 두 가지 방법 공부하는데 시간이 소요됐었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 개인적으로 코드로 작성하는게 편하더라구요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기획이나 디자인 변경으로 인해서 수정해야 할 때 xib는 불편한점이 많더라구요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에는 당연히 xib가 눈에 바로 보이는게 편했는데 뭔가 협업을 하다보니 어느덧 코드가 편해진게 신기하기도 하네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 가끔 계층 구조가 복잡한 view를 다룰 때에는 아직도 마음대로 잘 안될때가 많기도 해요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;앞으로 공부하고 보완해야 할 내용들&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;- Push, DeepLink, plugin 이해하기&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이쪽 관련 내용은 팀원들이 담당해서 하느라 아직 담당해보지 않은 부분이라 공부가 많이 필요해요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로 푸시, 공유 기능이 앱에서 핵심 기능이라 저도 얼른 배워서 신규 개발 시 적용해보고 싶네요 ㅎㅎ&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;- TDD, Appium, Combine 공부하기&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예전부터 TDD 도입한다 한다 했다가 아직 도입을 못한 상태인데&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 제 역량이 올라올 때 까지 팀원들이 기다려준 것 같아요 하하&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제는 도입하려 하는 것을 보니 미리미리 공부해서 얼타지 않고 잘 따라가 보려 합니다!!&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;- webview 띄우는 방식들 차이점 이해하기&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 서비스는 2가지 형태의 웹뷰를 사용하고 있는 것 같아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 페이지 형태의 webview랑 앱을 킬 때 바닥에 깔아놓는 webview 이렇게 2가지 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념은 알지만 사용할 때 어떻게 처리하고 개발 시 주의사항 같은 것은 무엇인지 공부해야 할 것 같아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목록 웹뷰(바닥에 깔려있는 웹뷰) -&amp;gt; 네이티브 -&amp;gt; 상세 웹뷰(신규)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPA구조로 인해 상세 웹뷰를 띄울 때 이전의 목록 웹뷰가 사라져서, 네이티브 화면에서 뒤로 가기 시 목록 웹뷰가 나오지 않는 이슈가 있어서 그렇게 했던 것 같아요.. 이 내용이 맞는지도 사실 잘 몰라서 확인이 필요해보여요ㅠㅠ&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;- 서버 관련 기초 지식 공부하기&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;협업 하다보면 서버분들과 커뮤니케이션 할일이 있곤 한데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL, SSO 같은 개념들을 잘 모르니 무슨 얘기인지 도통 이해를 못하겠더라구요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것도 틈틈히 공부하겠습니다!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적다보니 공부할것이 엄청 많은 것 같아요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년이라는 시간이 정말 빠르게 흘러간데에 비해 실력이 많이 성장했는지 의문이 많이 들기도 하고 걱정도 되고 하네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직은 팀원들이 하는 업무 대화를 온전히 이해 못하고 있는 것 같아서 답답할 때도 많긴한데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴수록 열심히 공부하는 수 밖에 없는 것 같아요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업무 적응도 어느 정도 했으니 내년에는 좀 더 성장한 상태로 회고를 작성했으면 하네요 ㅎㅎ&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>iOS</category>
      <category>ios</category>
      <category>개발자</category>
      <category>신입</category>
      <category>회고</category>
      <author>일해라토토</author>
      <guid isPermaLink="true">https://develop-toto.tistory.com/7</guid>
      <comments>https://develop-toto.tistory.com/7#entry7comment</comments>
      <pubDate>Sat, 30 Sep 2023 19:14:45 +0900</pubDate>
    </item>
    <item>
      <title>[RxSwift] Subscribe, Bind, Driver</title>
      <link>https://develop-toto.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 Subscribe, Bind, Driver의 차이점에 대해 정리해보려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소 rx로 개발을 하면서 아무 생각없이 복붙을 하면서 했었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 차이점이 있는지 알아보고 상황에 맞게 사용해보려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Subscribe&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드 내용을 확인해보면, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;onNext, onError, onCompleted, onDisposed 4가지의 parameter 가 존재&lt;/span&gt;하는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말그대로 구독한다는 개념이여서 무언가가 변하면 그 값을 받아오는 역할을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687678399008&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public func subscribe(
        onNext: ((Element) -&amp;gt; Void)? = nil,
        onError: ((Swift.Error) -&amp;gt; Void)? = nil,
        onCompleted: (() -&amp;gt; Void)? = nil,
        onDisposed: (() -&amp;gt; Void)? = nil
    ) -&amp;gt; Disposable {
            let disposable: Disposable
            
            if let disposed = onDisposed {
                disposable = Disposables.create(with: disposed)
            }
            else {
                disposable = Disposables.create()
            }
            
            #if DEBUG
                let synchronizationTracker = SynchronizationTracker()
            #endif
            
            let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
            
            let observer = AnonymousObserver&amp;lt;Element&amp;gt; { event in
                
                #if DEBUG
                    synchronizationTracker.register(synchronizationErrorMessage: .default)
                    defer { synchronizationTracker.unregister() }
                #endif
                
                switch event {
                case .next(let value):
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Bind&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 봤던 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Subscribe와 달리 parameter로 onNext만 가지고 있는 것이 차이점&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 에러 처리가 불가능하고, 간단하게 변경된 값을 전달만 하게되죠. &amp;nbsp;(onNext만 하는 Subscribe와 동일함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점으로는, observer가 추가될때마다 새로운 스트림이 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;옵저버가 늘어날때마다 스트림이 늘어나기 때문에 리소스적으로 낭비되게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687678573594&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public func bind(onNext: @escaping (Element) -&amp;gt; Void) -&amp;gt; Disposable {
        self.subscribe(onNext: onNext,
                       onError: { error in
                        rxFatalErrorInDebug(&quot;Binding error: \(error)&quot;)
                       })
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Drive&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서도 우선 parameter를 확인해보면 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;onError 가 빠져있는 것을 보니 에러처리가 불가능&lt;/span&gt;하겠네요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 MainScheduler 라고 적혀있기 때문에 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;메인스레드에서 동작하는 것을 보장&lt;/span&gt;하는 것이 특징입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;Bind와 다르게 하나의 스트림을 공유하기 때문에 리소스 측면에서 효율적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1687679007058&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public func drive(
        onNext: ((Element) -&amp;gt; Void)? = nil,
        onCompleted: (() -&amp;gt; Void)? = nil,
        onDisposed: (() -&amp;gt; Void)? = nil
    ) -&amp;gt; Disposable {
        MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage)
        return self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed)
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 Driver 사용 시 고려해야 할 사항이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;asDriver()를 통해 Drive Trait 을 부여해줘야 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 subject 타입은 error 나 completed 를 발생시키기 때문에, .asDriver(error: ) 이런식으로 변환하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Relay 타입은 error나 completed 를 발생시키지 않기 때문에, 그냥 .asDriver() 이렇게 변환하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #5f6d2b;&quot;&gt;&lt;b&gt;즉, UI 관련 작업을 하려면 Relay + Drive 조합&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #5f6d2b;&quot;&gt;&lt;b&gt;값을 저장하고 사용하려면 Subject + Subscirbe 조합&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>iOS</category>
      <category>BIND</category>
      <category>driver</category>
      <category>ios</category>
      <category>relay</category>
      <category>RxSwift</category>
      <category>subject</category>
      <category>subscribe</category>
      <author>일해라토토</author>
      <guid isPermaLink="true">https://develop-toto.tistory.com/6</guid>
      <comments>https://develop-toto.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 25 Jun 2023 17:20:22 +0900</pubDate>
    </item>
    <item>
      <title>[RxSwift] Subject, Relay</title>
      <link>https://develop-toto.tistory.com/5</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RxSwift에서 Subject, Relay에 대한 개념 및 특징을 학습하도록 하자&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;Subject&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;Subject = Observable + Observer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;개발을 하게 되면 Observable에 값을 추가하여,&lt;br /&gt;구독하고 있는 Subscriber가 알아챌 수 있도록 해야 하잖아요?&lt;br /&gt;&lt;br /&gt;이럴때 위처럼 Observable이자 Observer인 Subject를 사용하면 됩니다!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;Realy&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;기능은 대부분 유사한데, 차이점이 있다면 Rxcocoa 내에 Relay라는 객체를 사용하는 것 입니다.&lt;br /&gt;방출 시에는 .accept() 형태를 사용합니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;그리고 Dispose 되기 전까지는 계속 살아있기 때문에 UI작업에 주로 많이 사용한답니다! 오류가 발생해도 종료되지 않는 것이 특징입니다!&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Publish, Behavior, Replay.. 등등 매우 많지만 주로 사용하는 Publish 와 Behavior 를 알아보도록 하자&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;PublishSubject&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- default 값이 없다&lt;br /&gt;- 신규 subscriber 가 생기더라도 값을 방출하지 않는다&lt;br /&gt;- .completed, .error 이벤트로 종료된다&lt;br /&gt;- ex. 값이 생겼을때 새로 뷰를 그리거나 업데이트 할때 사용&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8HlTq/btsh6z6Emdy/Re8yhmhincFm7uBxRiKt90/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8HlTq/btsh6z6Emdy/Re8yhmhincFm7uBxRiKt90/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8HlTq/btsh6z6Emdy/Re8yhmhincFm7uBxRiKt90/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8HlTq%2Fbtsh6z6Emdy%2FRe8yhmhincFm7uBxRiKt90%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1125&quot; height=&quot;784&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;784&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;BehaviorSubject&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- default 값을 필수로 설정해주어야 함&lt;br /&gt;- 신규 subscriber 가 생기면 즉시 현재 가지고 있는 값을 방출한다. (그래서 default값을 설정하나봄)&lt;br /&gt;&lt;b&gt;- ex. 최신 값을 계속 보여줘야 하는 경우에 사용&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G776p/btsh9BDjgfH/7CSr8bdSWAqj8vmqR8Tqa0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G776p/btsh9BDjgfH/7CSr8bdSWAqj8vmqR8Tqa0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G776p/btsh9BDjgfH/7CSr8bdSWAqj8vmqR8Tqa0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG776p%2Fbtsh9BDjgfH%2F7CSr8bdSWAqj8vmqR8Tqa0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1125&quot; height=&quot;762&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;PublishRelay&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;-위와 동일하게 default 값이 없음&lt;br /&gt;- accept 이벤트가 들어온 경우에만 값 방출&lt;br /&gt;- 현재 가지고 있는 값 접근 불가&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;BehaviorRelay&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 여기도 default 값이 있음&lt;br /&gt;- &lt;span style=&quot;color: #ef5369;&quot;&gt;현재 가지고 있는 값에 접근해서 사용할 수 있음(읽기 전용이긴 함)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;결론&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;- Relay 는 에러가 발생해도 유지되기 때문에 UI 작업에 많이 사용한다.&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;- Behavior 는 기본값을 가지며, 현재 값에 접근할 수 있으며, 구독하는 즉시 값이 방출된다.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;학습하며 정리한 내용이라 잘못된 내용이 포함되어 있을 수 있습니다. 틀리거나 수정이 필요한 부분 댓글로 알려주시면 감사하겠습니다!&lt;/p&gt;</description>
      <category>iOS</category>
      <category>ios</category>
      <category>relay</category>
      <category>RxSwfit</category>
      <category>subject</category>
      <author>일해라토토</author>
      <guid isPermaLink="true">https://develop-toto.tistory.com/5</guid>
      <comments>https://develop-toto.tistory.com/5#entry5comment</comments>
      <pubDate>Wed, 31 May 2023 21:52:09 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] layoutIfNeeded 함수에 대해 알아보자</title>
      <link>https://develop-toto.tistory.com/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;오늘은 layoutIfNeeded 함수에 대해 알아봅시다.&lt;br&gt;&amp;nbsp;&lt;br&gt;기본적인 Life Cycle 에 대해서는 알고 가정하고 진행하겠습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;layoutIfNeeded 함수는 한 마디로 view 의 layout 을 갱신시키고 싶을 때 사용하는 함수 입니다!&lt;br&gt;&amp;nbsp;&lt;br&gt;iOS 에서는 초당 60번 정도 View 를 업데이트 한다고 합니다.&lt;br&gt;즉, 1/60 초 마다 화면을 업데이트 해준다는거겠죠?&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;근데 만약에 1/60 초를 기다리지 않고 바로 view 를 업데이트 하고 싶을 수도 있잖아요??&lt;br&gt;이럴때 layoutIfNeeded 함수를 호출해주면 됩니다!&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;자 조금 더 자세하게 설명해보자면,&amp;nbsp;아래와 같은 Main Run Loop 와 Update Cycle 을 가지고 있습니다.&lt;br&gt;각각에 대해 알아보도록 하죠&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X1Y0u/btr61hhddYm/aPkTekkxRkkQn6Tcjlcy41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X1Y0u/btr61hhddYm/aPkTekkxRkkQn6Tcjlcy41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X1Y0u/btr61hhddYm/aPkTekkxRkkQn6Tcjlcy41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX1Y0u%2Fbtr61hhddYm%2FaPkTekkxRkkQn6Tcjlcy41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;231&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Main Run Loop&lt;br&gt;&amp;nbsp;터치, 회전과 같은 이벤트 들을 처리하는 역할&lt;br&gt;&amp;nbsp;&lt;br&gt;- Update Cycle&lt;br&gt;Main Run Loop 에서 들어온 이벤트 들을 처리하는 역할 (ex. layout 재배치, view 다시그리기)&lt;br&gt;&lt;br&gt;만약에 제가 버튼을 눌러서 A라는 view의 높이가 변했다고 가정합시다.&lt;br&gt;&lt;br&gt;그러면 버튼을 눌렀을때의 이벤트는 Main Run Loop 에 쌓이고, A view의 높이 변경은 Update Cycle 에서 처리하는 겁니다!&lt;br&gt;&lt;br&gt;이처럼 view의 layout, position 을 변경하게 될 경우, Main Run Loop에서 즉각적으로 처리되지 않습니다.&amp;nbsp;&amp;nbsp;일종의 시간차가 있다고 생각하시면 됩니다 ㅎㅎ&lt;br&gt;&lt;br&gt;즉각적으로 처리하려면 layoutIfNeeded 함수를 호출하면 됩니다!!!&lt;br&gt;&lt;br&gt;유사한 기능을 하는 함수가 있는데 layoutIfNeeded 함수는 동기적으로 실행되며, 애니메이션에 적용하면 즉시 반영되어 눈에 보일 겁니다!!&lt;/p&gt;</description>
      <author>일해라토토</author>
      <guid isPermaLink="true">https://develop-toto.tistory.com/4</guid>
      <comments>https://develop-toto.tistory.com/4#entry4comment</comments>
      <pubDate>Fri, 31 Mar 2023 18:46:27 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] isUserInteractionEnabled</title>
      <link>https://develop-toto.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 &lt;b&gt;&lt;span&gt;isUserInteractionEnabled &lt;/span&gt;&lt;/b&gt;&lt;span&gt;에 대해서 알아보도록 해요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;평소에 개발하면서 gesture event에 대해서 알고 있으면 좋을 것 같아 정리해보려 합니다~&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;우선 &lt;b&gt;&lt;span&gt;isUserInteractionEnabled이 무엇이냐?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공홈에 정리되어 있기로는,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1622&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eNzM6e/btr1fO5ExL6/wmP1m6fHf9skcCPAhgiu51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eNzM6e/btr1fO5ExL6/wmP1m6fHf9skcCPAhgiu51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eNzM6e/btr1fO5ExL6/wmP1m6fHf9skcCPAhgiu51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeNzM6e%2Fbtr1fO5ExL6%2FwmP1m6fHf9skcCPAhgiu51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1622&quot; height=&quot;404&quot; data-origin-width=&quot;1622&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;b&gt;말그대로 user event에 대한 interaction 을 가능하게 하도록 할 것이냐 입니다.&lt;/b&gt;&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 user event 에는 &lt;b&gt;touch, press, keyboard, focus&lt;/b&gt; 같은 이벤트들을 말합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvS4oP/btr1dmuSqOx/UMgVUXCEf7puiEpSmUonP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvS4oP/btr1dmuSqOx/UMgVUXCEf7puiEpSmUonP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvS4oP/btr1dmuSqOx/UMgVUXCEf7puiEpSmUonP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvS4oP%2Fbtr1dmuSqOx%2FUMgVUXCEf7puiEpSmUonP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;215&quot; height=&quot;271&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 위 사진처럼 버튼이&lt;span&gt; &lt;/span&gt;밑에&lt;span&gt; &lt;/span&gt;깔려있고&lt;span&gt;, Label &lt;/span&gt;이&lt;span&gt; &lt;/span&gt;그&lt;span&gt; &lt;/span&gt;위에&lt;span&gt; &lt;/span&gt;있는&lt;span&gt; &lt;/span&gt;경우에는&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Label &lt;/span&gt;의&lt;span&gt; &lt;/span&gt;터치&lt;span&gt; &lt;/span&gt;이벤트는&lt;span&gt;&amp;nbsp;작동하지 않습니다!!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜냐하면 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;UILabel 의 isUserInteractionEnabled 값은 false 이기 때문입니다!&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Label 밑에 있는 Button 의 경우 true 값을 가지고 있어서 통과(?)하게 되고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;touch event 를 Button 이 가져가게 됩니다!!&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;그래서 true 로 바꿔주어야 맨 위에 있는 Label을 통과(?) 건너뛰지(?) 않고 바로 touch event 를 처리할 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그러면 Label 에 대한 touch event는 어떻게 처리하는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;UILabel, UIImageView 의 경우 UIView 를 모두 상속하고 있답니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 모두 false 값을 기본적으로 가지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbD4I5/btr0RKqohhY/6kK6S8oZLJzCU9ugouc4R1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbD4I5/btr0RKqohhY/6kK6S8oZLJzCU9ugouc4R1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbD4I5/btr0RKqohhY/6kK6S8oZLJzCU9ugouc4R1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbD4I5%2Fbtr0RKqohhY%2F6kK6S8oZLJzCU9ugouc4R1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;81&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/basUhs/btr1lBycB3W/7ojt1RMeQXEpDDy6PVTuZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/basUhs/btr1lBycB3W/7ojt1RMeQXEpDDy6PVTuZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/basUhs/btr1lBycB3W/7ojt1RMeQXEpDDy6PVTuZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbasUhs%2Fbtr1lBycB3W%2F7ojt1RMeQXEpDDy6PVTuZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;69&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 따라서 touch event 처리 시 다르게 처리해줘야 합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;- UIButton 터치 이벤트 처리&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;swift&quot; data-ke-language=&quot;swift&quot;&gt;&lt;code&gt;button.addTarget(self, action: #selector(onClick), for: .touchUpInside)

@objc func onClick() {
  print(&quot;button clicked&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼은 기본적으로 &lt;b&gt;&lt;span&gt;isUserInteractionEnabled 값이 &amp;nbsp;true 라서 &lt;span style=&quot;color: #ef5369;&quot;&gt;addTarget()&lt;/span&gt; 함수로 처리해주면 됩니다!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;- UIView 터치 이벤트 처리&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;swift&quot; data-ke-language=&quot;swift&quot;&gt;&lt;code&gt;let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didViewTapped(_:)))
view.addGestureRecognizer(tapGesture)
view.isUserInteractionEnabled = true  // 제일 중요한 부분!
        
@objc func didViewTapped(_ gesture: UITapGestureRecognizer) {
   print(&quot;view clicked&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;view 는 우선&amp;nbsp;&lt;b&gt;&lt;span&gt;isUserInteractionEnabled 값이 false 라서 true 로 변경해주어야 터치가 가능해집니다..!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;그리고 &lt;span style=&quot;color: #ef5369;&quot;&gt;addGestureRecognizer()&lt;/span&gt; 함수를 통해서 제스처가 발생한 것을 알아챌 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;요약&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;* UIButton - True, addTarget 함수를 통해 타겟 액션 등록&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;i&gt;* UIView - False, addGestureRecognizer 함수를 통해 제스처 등록&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 정의는 &lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiview/1622577-isuserinteractionenabled&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/uikit/uiview/1622577-isuserinteractionenabled&lt;/a&gt;&amp;nbsp;에서 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>iOS</category>
      <category>ios</category>
      <category>isUserInteractionEnabled</category>
      <category>Swift</category>
      <category>UIButton</category>
      <category>UILabel</category>
      <category>UIView</category>
      <author>일해라토토</author>
      <guid isPermaLink="true">https://develop-toto.tistory.com/3</guid>
      <comments>https://develop-toto.tistory.com/3#entry3comment</comments>
      <pubDate>Tue, 28 Feb 2023 23:50:45 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] Clean Architecture</title>
      <link>https://develop-toto.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Clean Architecture 에 대해 알아보도록 합시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 개발 시 다양한 디자인 패턴이 존재하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직까지 대부분의 프로젝트에서는 MVVM 패턴을 많이 사용하는 것 같아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로버트.C.마틴 뭐시기 어떤분이 썼다고는 하는데 거기까지는 알 필요 없으니 넘어가도록 합시당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;궁금하신 분은 여기서 확인 ㄱㄱ &lt;a href=&quot;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674383748649&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Clean Coder Blog&quot; data-og-description=&quot;The Clean Architecture 13 August 2012 Over the last several years we&amp;rsquo;ve seen a whole range of ideas regarding the architecture of systems. These include: Though these architectures all vary somewhat in their details, they are very similar. They all have &quot; data-og-host=&quot;blog.cleancoder.com&quot; data-og-source-url=&quot;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&quot; data-og-url=&quot;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dxhTrf/hyRmY29O3j/KYx0K2XvotJvs5E6K6KTHk/img.jpg?width=772&amp;amp;height=567&amp;amp;face=0_0_772_567,https://scrap.kakaocdn.net/dn/9IZlL/hyRloPW2Rp/cP3H81QKRLjsbZMng0hiD1/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dxhTrf/hyRmY29O3j/KYx0K2XvotJvs5E6K6KTHk/img.jpg?width=772&amp;amp;height=567&amp;amp;face=0_0_772_567,https://scrap.kakaocdn.net/dn/9IZlL/hyRloPW2Rp/cP3H81QKRLjsbZMng0hiD1/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Clean Coder Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Clean Architecture 13 August 2012 Over the last several years we&amp;rsquo;ve seen a whole range of ideas regarding the architecture of systems. These include: Though these architectures all vary somewhat in their details, they are very similar. They all have&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.cleancoder.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;클린 아키텍처가 뭔가요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Soc(Separate of Concerns) 관심사의 분리를 하여 관리하는 의존 규칙이 있긴한데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;걍 우선은 3개의 계층(layer)으로 나누어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각자의 할일을 나눈다고만 생각하고 넘어갑시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1716&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blfQYM/btrWRjpJ5fl/AqIlYhUKpdb5tl7d9Sbn1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blfQYM/btrWRjpJ5fl/AqIlYhUKpdb5tl7d9Sbn1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blfQYM/btrWRjpJ5fl/AqIlYhUKpdb5tl7d9Sbn1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblfQYM%2FbtrWRjpJ5fl%2FAqIlYhUKpdb5tl7d9Sbn1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1716&quot; height=&quot;412&quot; data-origin-width=&quot;1716&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Presentation Layer -&amp;gt; 화면에 직접적으로 보이도록 하는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Domain Layer -&amp;gt; 비즈니스 로직, 즉 데이터들을 입맛에 맞게 가공하고 변환하는 곳?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Data Layer -&amp;gt; 데이터 가져오는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(제 맘대로 해석한거니 정확하진 않습니다..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그래서 이걸 어떻게 쓰면 되느냐&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진처럼 폴더 구조를 만들면 끝입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정신없으니 핵심적이고 중요한 것만 빠르게 정리해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWes39/btrWUHv7pFW/39NkwX2dAKtkb5PBUO9k70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWes39/btrWUHv7pFW/39NkwX2dAKtkb5PBUO9k70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWes39/btrWUHv7pFW/39NkwX2dAKtkb5PBUO9k70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWes39%2FbtrWUHv7pFW%2F39NkwX2dAKtkb5PBUO9k70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1722&quot; height=&quot;816&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 맨 위에 있는 &lt;b&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;Domain Layer&lt;/span&gt;&lt;/b&gt; 부터 확인해보죠&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lH3cA/btrWWrNcmuA/9GqzYYdVxspy6SQxSsdYWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lH3cA/btrWWrNcmuA/9GqzYYdVxspy6SQxSsdYWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lH3cA/btrWWrNcmuA/9GqzYYdVxspy6SQxSsdYWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlH3cA%2FbtrWWrNcmuA%2F9GqzYYdVxspy6SQxSsdYWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;198&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Entity&lt;/b&gt;: Model 형태로 데이터들을 선언해놓음. ex. 영화목록Model, 영화상세Model..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;UseCase&lt;/b&gt;: 비즈니스 로직 ex. 영화 목록 가져와줘, 영화 상세 내용 가져와줘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 &lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Presentation Layer&lt;/b&gt;&lt;/span&gt; 를 보도록 하죠&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQFe3O/btrWRyAgj3S/lMFCvke254IIcKw5tQnNfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQFe3O/btrWRyAgj3S/lMFCvke254IIcKw5tQnNfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQFe3O/btrWRyAgj3S/lMFCvke254IIcKw5tQnNfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQFe3O%2FbtrWRyAgj3S%2FlMFCvke254IIcKw5tQnNfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;162&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;viewModel&lt;/b&gt;: useCase 를 호출해서 view가 load 되거나 update 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;view&lt;/b&gt;: 말그대로 화면을 보여줍니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 &lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Data Layer&lt;/b&gt;&lt;/span&gt; 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;322&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR12c9/btrWYMwGTcH/ucJHeaKX5k2wsbMq0hk7b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR12c9/btrWYMwGTcH/ucJHeaKX5k2wsbMq0hk7b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR12c9/btrWYMwGTcH/ucJHeaKX5k2wsbMq0hk7b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR12c9%2FbtrWYMwGTcH%2FucJHeaKX5k2wsbMq0hk7b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;322&quot; height=&quot;150&quot; data-origin-width=&quot;322&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;repository&lt;/b&gt;: 실제로 API 를 쏴서 데이터를 가져오는 곳 ex. fetch영화목록()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 요약해보자면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약에 예시로 영화 목록을 조회하는 기능을 만들고 싶다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러려면 우선 API를 쏴서 영화 목록 데이터를 가져와야겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 순서대로 함수 호출을 하면 됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;i&gt;영화목록view -&amp;gt; 영화목록viewModel -&amp;gt; 영화useCase -&amp;gt; 영화repository&amp;nbsp;&lt;/i&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 가져온 데이터를 view에 띄워야겠죠?&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;i&gt;entity 형태로 API response를 받아오게 됩니다.&lt;/i&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 entity 를 view 에 전달해서 화면에 그려주면 끝입니다!!!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대한 간단하게 써보려 노력했는데 틀린 내용이 있을 수도 있으니&amp;nbsp;참고만 부탁드립니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘못된 내용은 댓글에 남겨주시면 수정하도록 하겠습니다!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 내용은 아래 깃허브 링크 참고 부탁드립니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kudoleh/iOS-Clean-Architecture-MVVM&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/kudoleh/iOS-Clean-Architecture-MVVM&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674387304217&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - kudoleh/iOS-Clean-Architecture-MVVM: Template iOS app using Clean Architecture and MVVM. Includes DIContainer, FlowCoor&quot; data-og-description=&quot;Template iOS app using Clean Architecture and MVVM. Includes DIContainer, FlowCoordinator, DTO, Response Caching and one of the views in SwiftUI - GitHub - kudoleh/iOS-Clean-Architecture-MVVM: Tem...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/kudoleh/iOS-Clean-Architecture-MVVM&quot; data-og-url=&quot;https://github.com/kudoleh/iOS-Clean-Architecture-MVVM&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jPgsI/hyRnd0k6mV/i9Fu1WYXkjqKZOSHOOjV2K/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_121_1038_167&quot;&gt;&lt;a href=&quot;https://github.com/kudoleh/iOS-Clean-Architecture-MVVM&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/kudoleh/iOS-Clean-Architecture-MVVM&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jPgsI/hyRnd0k6mV/i9Fu1WYXkjqKZOSHOOjV2K/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_121_1038_167');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - kudoleh/iOS-Clean-Architecture-MVVM: Template iOS app using Clean Architecture and MVVM. Includes DIContainer, FlowCoor&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Template iOS app using Clean Architecture and MVVM. Includes DIContainer, FlowCoordinator, DTO, Response Caching and one of the views in SwiftUI - GitHub - kudoleh/iOS-Clean-Architecture-MVVM: Tem...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>iOS</category>
      <category>Clean Architecture</category>
      <category>ios</category>
      <category>MVVM</category>
      <category>Swift</category>
      <author>일해라토토</author>
      <guid isPermaLink="true">https://develop-toto.tistory.com/2</guid>
      <comments>https://develop-toto.tistory.com/2#entry2comment</comments>
      <pubDate>Sun, 22 Jan 2023 20:37:53 +0900</pubDate>
    </item>
  </channel>
</rss>