<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>본질의 중요성</title>
    <link>https://you9010.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 7 Jul 2026 21:03:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>you90100</managingEditor>
    <item>
      <title>iOS 접근성 개발 참고 자료</title>
      <link>https://you9010.tistory.com/325</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Accessibility for UIKit&lt;/h2&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://developer.apple.com/documentation/uikit/accessibility_for_uikit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/uikit/accessibility_for_uikit&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Supporting VoiceOver in Your App&lt;/h2&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://developer.apple.com/documentation/uikit/accessibility_for_ios_and_tvos/supporting_voiceover_in_your_app&quot;&gt;https://developer.apple.com/documentation/uikit/accessibility_for_ios_and_tvos/supporting_voiceover_in_your_app&lt;/a&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;The &lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619577-accessibilitylabel&quot;&gt;&lt;span style=&quot;color: #dca10d;&quot;&gt;accessibilityLabel&lt;/span&gt;&lt;/a&gt; property provides descriptive text that VoiceOver reads when the user selects an element.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619585-accessibilityhint&quot;&gt;&lt;span style=&quot;color: #dca10d;&quot;&gt;accessibilityHint&lt;/span&gt;&lt;/a&gt; property provides additional context (or actions) for the selected element.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Accessibility for iOS Developer Guide&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 접근성 관련해서 정말 잘 설명되어있는 가이드 페이지!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://a11y-guidelines.orange.com/en/mobile/ios/development/&quot;&gt;https://a11y-guidelines.orange.com/en/mobile/ios/development/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1629872628214&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;iOS developer guide - Orange digital accessibility guidelines&quot; data-og-description=&quot;VoiceOver must vocalize every informative element with a high degree of quality in order to let the user know and perfectly understand the context of the consulted page. The accuracy of this vocalization is done through four attributes: label, hint, value &quot; data-og-host=&quot;a11y-guidelines.orange.com&quot; data-og-source-url=&quot;https://a11y-guidelines.orange.com/en/mobile/ios/development/&quot; data-og-url=&quot;https://a11y-guidelines.orange.com/en/mobile/ios/development/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cYuUip/hyLnD4XVjZ/MAYRLKcdx8M5OQJyOksql0/img.png?width=600&amp;amp;height=753&amp;amp;face=0_0_600_753,https://scrap.kakaocdn.net/dn/SveNo/hyLnumEDhB/A9KiBb76L0Gb6vvsl6QYiK/img.png?width=500&amp;amp;height=307&amp;amp;face=0_0_500_307,https://scrap.kakaocdn.net/dn/yCwnI/hyLmUmZ5QE/IswhIKzPPwN0nL5kzF76Dk/img.png?width=700&amp;amp;height=218&amp;amp;face=0_0_700_218&quot;&gt;&lt;a href=&quot;https://a11y-guidelines.orange.com/en/mobile/ios/development/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://a11y-guidelines.orange.com/en/mobile/ios/development/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cYuUip/hyLnD4XVjZ/MAYRLKcdx8M5OQJyOksql0/img.png?width=600&amp;amp;height=753&amp;amp;face=0_0_600_753,https://scrap.kakaocdn.net/dn/SveNo/hyLnumEDhB/A9KiBb76L0Gb6vvsl6QYiK/img.png?width=500&amp;amp;height=307&amp;amp;face=0_0_500_307,https://scrap.kakaocdn.net/dn/yCwnI/hyLmUmZ5QE/IswhIKzPPwN0nL5kzF76Dk/img.png?width=700&amp;amp;height=218&amp;amp;face=0_0_700_218');&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;iOS developer guide - Orange digital accessibility guidelines&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;VoiceOver must vocalize every informative element with a high degree of quality in order to let the user know and perfectly understand the context of the consulted page. The accuracy of this vocalization is done through four attributes: label, hint, value&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;a11y-guidelines.orange.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;h2 data-ke-size=&quot;size26&quot;&gt;Raywenderlich의 Accessibility 가이드 페이지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.raywenderlich.com/6827616-ios-accessibility-getting-started&quot;&gt;https://www.raywenderlich.com/6827616-ios-accessibility-getting-started&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1629871176048&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;iOS Accessibility: Getting Started&quot; data-og-description=&quot;In this iOS accessibility tutorial, learn how to make apps more accessible using VoiceOver and the Accessibility inspector.&quot; data-og-host=&quot;www.raywenderlich.com&quot; data-og-source-url=&quot;https://www.raywenderlich.com/6827616-ios-accessibility-getting-started&quot; data-og-url=&quot;https://www.raywenderlich.com/6827616-ios-accessibility-getting-started&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbXVLc/hyLnA8egKM/l8KGSYGu72cvYuqhdJlmgk/img.png?width=1800&amp;amp;height=900&amp;amp;face=0_0_1800_900,https://scrap.kakaocdn.net/dn/c43Ptn/hyLmOAiElj/ollgwa1UQN367oMUHXXh8k/img.png?width=1800&amp;amp;height=900&amp;amp;face=0_0_1800_900&quot;&gt;&lt;a href=&quot;https://www.raywenderlich.com/6827616-ios-accessibility-getting-started&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.raywenderlich.com/6827616-ios-accessibility-getting-started&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbXVLc/hyLnA8egKM/l8KGSYGu72cvYuqhdJlmgk/img.png?width=1800&amp;amp;height=900&amp;amp;face=0_0_1800_900,https://scrap.kakaocdn.net/dn/c43Ptn/hyLmOAiElj/ollgwa1UQN367oMUHXXh8k/img.png?width=1800&amp;amp;height=900&amp;amp;face=0_0_1800_900');&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;iOS Accessibility: Getting Started&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this iOS accessibility tutorial, learn how to make apps more accessible using VoiceOver and the Accessibility inspector.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.raywenderlich.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.raywenderlich.com/4720178-ios-accessibility-tutorial-making-custom-controls-accessible&quot;&gt;https://www.raywenderlich.com/4720178-ios-accessibility-tutorial-making-custom-controls-accessible&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1629871186794&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;iOS Accessibility Tutorial: Making Custom Controls Accessible&quot; data-og-description=&quot;In this iOS accessibility tutorial, you&amp;rsquo;ll learn to make custom controls accessible using VoiceOver, elements group, custom action, traits, frame and more.&quot; data-og-host=&quot;www.raywenderlich.com&quot; data-og-source-url=&quot;https://www.raywenderlich.com/4720178-ios-accessibility-tutorial-making-custom-controls-accessible&quot; data-og-url=&quot;https://www.raywenderlich.com/4720178-ios-accessibility-tutorial-making-custom-controls-accessible&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WTwcl/hyLnwLxASj/I3eqax68gXZ4cBZoYvg9g0/img.png?width=1800&amp;amp;height=900&amp;amp;face=1434_635_1633_851&quot;&gt;&lt;a href=&quot;https://www.raywenderlich.com/4720178-ios-accessibility-tutorial-making-custom-controls-accessible&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.raywenderlich.com/4720178-ios-accessibility-tutorial-making-custom-controls-accessible&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WTwcl/hyLnwLxASj/I3eqax68gXZ4cBZoYvg9g0/img.png?width=1800&amp;amp;height=900&amp;amp;face=1434_635_1633_851');&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;iOS Accessibility Tutorial: Making Custom Controls Accessible&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this iOS accessibility tutorial, you&amp;rsquo;ll learn to make custom controls accessible using VoiceOver, elements group, custom action, traits, frame and more.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.raywenderlich.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;h2 data-ke-size=&quot;size26&quot;&gt;시뮬레이터에서 접근성 테스트 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XCode &amp;gt; Open Developer Tool &amp;gt; Accessibility Insepector&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/iOS 본질을 파헤치쟈</category>
      <category>iOS accessibility</category>
      <category>iOS voiceover</category>
      <category>iOS 접근성</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/325</guid>
      <comments>https://you9010.tistory.com/325#entry325comment</comments>
      <pubDate>Wed, 25 Aug 2021 15:26:57 +0900</pubDate>
    </item>
    <item>
      <title>실용주의 프로그래머 책을 시작하며 ... + 서문</title>
      <link>https://you9010.tistory.com/324</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;연차가 쌓일수록 나에게 멘토가 필요했다.&lt;br /&gt;그 멘토를 찾는 과정에서 발견한 이 책.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책의 부제는 '&lt;u&gt;숙련공에서 마스터로&lt;/u&gt;' 이다.&lt;br /&gt;숙련공이 마스터가 되는 것은 단순한 기계적 학습이 아닌, &lt;b&gt;지혜&lt;/b&gt;가 필요하다.&lt;br /&gt;마스터로부터 그런 통찰과 직관, 지혜를 배울 수 있는 책.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책을 정독하고, 블로그에 내용을 정리할 예정이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실용주의란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 특정 기술에 매이면 안 되며, 개별 상황마다 그 상황에서 좋은 해결방안을 고를 수 있도록 충분한 배경지식과 경험을 가지는 것.&lt;br /&gt;배경지식은 컴퓨터 과학의 기본 원리들을 이해하는 것이서 나오고, 경험은 다양한 범위의 실제 프로젝트들을 수행해보는 것에서 나온다.&lt;br /&gt;이론과 실천의 결합은 우리를 강하게 만든다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;무엇이 실용주의 프로그래머를 만드는가?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;얼리어덥터 성향 / 새로운 것에 빨리 적응하는 성향&lt;/li&gt;
&lt;li&gt;캐묻기 좋아한다.&lt;/li&gt;
&lt;li&gt;비판적인 사고의 소유자&lt;/li&gt;
&lt;li&gt;현실적이다.&lt;/li&gt;
&lt;li&gt;다방면의 기술에 익숙하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실용주의 프로그래머 Tip&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 실용주의 프로그래머가 되기 위한 많은 팁을 제공한다. 그중에 이 장에서는 두가지 ...&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;자신의 기술(craft)에 관심과 애정을 가져라.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;자신의 일에 대해 생각하면서 일하라!&lt;/span&gt;&lt;br /&gt;- 모든 개발 과정에서, 매일, 우리가 내리는 모든 결정을 지속적이고 비판적으로 평가해보는 것.&lt;br /&gt;- 절대 기계적으로 일하지 말라. 언제나 생각하고, 언제나 일하면서, 동시에 자신의 일을 비평하고 분석하라.&lt;br /&gt;- 오래된 IBM의 표어인 생각하라!(THINK!) 가 실용주의 프로그래머의 주문(mantra)이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이것은 끊임없이 지속되는 과정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매일 같이 지금 있는 기술들을 더 다듬고, 우리 기술 목록에 새로운 도구들을 추가하라.&amp;nbsp;&lt;br /&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;Reference.&lt;br /&gt;The&amp;nbsp;Pragmatic&amp;nbsp;Programmer:&amp;nbsp;From&amp;nbsp;Journeyman&amp;nbsp;to&amp;nbsp;Master by Andrew Hunt, David&amp;nbsp;Thomas&amp;nbsp;&lt;/p&gt;</description>
      <category>실용주의 프로그래머</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/324</guid>
      <comments>https://you9010.tistory.com/324#entry324comment</comments>
      <pubDate>Tue, 10 Aug 2021 23:39:55 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] UNUserNotificationCenter, Push Notification 권한 요청 방법</title>
      <link>https://you9010.tistory.com/322</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UNUserNotificationCenter란?&lt;/li&gt;
&lt;li&gt;Push Notification 사용 권한 요청&lt;br /&gt;1. UNUserNotificationCenterDelegate 채택&lt;br /&gt;2. Notification 권한 부여 요청&lt;br /&gt;3.&amp;nbsp;APNS(Apple Push Notification Service)에 등록&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;UNUserNotificationCenter란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱과 앱 익스텐션에&amp;nbsp;대한&amp;nbsp;알림&amp;nbsp;관련&amp;nbsp;작업을&amp;nbsp;관리하기&amp;nbsp;위한 센트럴 오브젝트.&lt;br /&gt;공유된 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;UNUserNotificationCenter&lt;/span&gt; 객체를 사용하여 앱과 앱 확장의 모든 알림 관련 동작을 관리한다.&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;Push Notification 사용 권한 요청&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알림에&amp;nbsp;응답하여 &lt;u&gt;알럿&lt;/u&gt;을 표시하거나,&amp;nbsp;&lt;u&gt;소리&lt;/u&gt;를&amp;nbsp;재생하거나,&amp;nbsp;앱&amp;nbsp;아이콘에&amp;nbsp;&lt;u&gt;배지&lt;/u&gt;를&amp;nbsp;달&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;권한을&amp;nbsp;요청하는 방법에 대해 알아보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;324&quot; data-filename=&quot;스크린샷 2021-07-12 오후 11.18.17.png&quot; width=&quot;300&quot; height=&quot;211&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d76aC4/btq9qlhk3sq/5n1UgssZKyRyR49UtbpV8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d76aC4/btq9qlhk3sq/5n1UgssZKyRyR49UtbpV8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d76aC4/btq9qlhk3sq/5n1UgssZKyRyR49UtbpV8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd76aC4%2Fbtq9qlhk3sq%2F5n1UgssZKyRyR49UtbpV8K%2Fimg.png&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;324&quot; data-filename=&quot;스크린샷 2021-07-12 오후 11.18.17.png&quot; width=&quot;300&quot; height=&quot;211&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;h4 data-ke-size=&quot;size20&quot;&gt;1. UNUserNotificationCenterDelegate 채택&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알림 관련 작업을 처리하려면 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;UNUserNotificationCenterDelegate&lt;/span&gt; 프로토콜을 채택하는 객체를 생성하여 이 객체의 델리게이트 프로퍼티에 할당한다. 이 작업은 해당 델리게이트와 상호작용을 할 수 있는 다른 작업을 수행 하기 전에 이 델리게이트 프로퍼티에 객체를 항상 할당하자.&lt;/p&gt;
&lt;pre id=&quot;code_1626100065371&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -&amp;gt; Bool {
        UNUserNotificationCenter.current().delegate = self
        return true
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Notification 권한 부여 요청&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;승인을 요청하려면, &lt;span style=&quot;background-color: #dddddd;&quot;&gt;UNUserNotificationCenter&lt;/span&gt; 인스턴스를 가져와서 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;requestAuthorization(options:completionHandler:)&amp;nbsp;&lt;/span&gt;을 호출하자. (&lt;b&gt;alert&lt;/b&gt;, &lt;b&gt;sound&lt;/b&gt;, &lt;b&gt;badge&lt;/b&gt; 타입 요청 가능)&lt;/p&gt;
&lt;pre id=&quot;code_1625554882237&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 20px; color: #383a42; background-color: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
    
    if let error = error {
        // Handle the error here.
    }
    
    // Enable or disable features based on the authorization.
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.&amp;nbsp;APNS(Apple Push Notification Service)에 원격 알림을 수신하도록 등록&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple Push Notification Service에 등록 프로세스를 시작하려면 아래 메소드를 호출하자. (&lt;u&gt;&lt;b&gt;Main Thread에서 진행해야함.&lt;/b&gt;&lt;/u&gt;)&lt;/p&gt;
&lt;pre id=&quot;code_1626101072345&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DispatchQueue.main.async {
    UIApplication.shared.registerForRemoteNotifications()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등록이 성공되었다면, 앱은 앱 델리게이트 객체의 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;application(_:didRegisterForRemoteNotificationsWithDeviceToken:)&lt;/span&gt; 메소드를 호출하여 &lt;b&gt;&lt;u&gt;디바이스 토큰&lt;/u&gt;&lt;/b&gt;을 전달함. (디바이스의 원격 알림을 생성하기 위해서는 서버에 이 토큰을 전달해야함.)&lt;/p&gt;
&lt;pre id=&quot;code_1626101773552&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등록이 실패되었다면, 앱은 앱 델리게이트 객체의 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;application(_:didFailToRegisterForRemoteNotificationsWithError:)&lt;/span&gt; 메소드를 호출한다.&lt;/p&gt;
&lt;pre id=&quot;code_1626101788724&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
}&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;p data-ke-size=&quot;size16&quot;&gt;Ref.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/usernotifications/unusernotificationcenter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/usernotifications/unusernotificationcenter&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiapplication/1623078-registerforremotenotifications&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/uikit/uiapplication/1623078-registerforremotenotifications&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>iOS/iOS 본질을 파헤치쟈</category>
      <category>apns</category>
      <category>iOS device token</category>
      <category>iOS Push</category>
      <category>iOS 푸시 권한</category>
      <category>iOS 푸시 등록</category>
      <category>registerForRemoteNotifications</category>
      <category>UNUserNotificationCenter</category>
      <category>UNUserNotificationCenterDelegate</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/322</guid>
      <comments>https://you9010.tistory.com/322#entry322comment</comments>
      <pubDate>Tue, 6 Jul 2021 16:01:55 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] iOS 애플리케이션 실행 순서, UIApplicationMain, @main</title>
      <link>https://you9010.tistory.com/321</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;C언어 기반의 프로그래밍 언어에서는 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;main&lt;/span&gt;이라는 함수가 앱의 시작이 된다.&lt;br /&gt;iOS 앱 또한 Objective-C 기반에서 돌아가기 때문에 앱은 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;main&lt;/span&gt; 함수에서 시작된다.&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;iOS 애플리케이션 실행 순서&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;main 함수 실행&lt;/li&gt;
&lt;li&gt;main 함수에서 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;UIApplicationMain&lt;/span&gt; 함수 실행 (앱의 본체에 해당하는 객체인 UIApplication 객체 생성)&lt;/li&gt;
&lt;li&gt;Info.plist 파일을 읽어들여 파일에 기록된 정보를 참고하여 그 외에 필요한 데이터 로드.&lt;br /&gt;(Main nib 파일을 사용하는 경우 이 과정에서 로드됨.)&lt;/li&gt;
&lt;li&gt;Main nib 파일이 없거나 그 속에서 앱 델리게이트가 없는 경우, 앱 델리게이트 객체를 만들고 앱 객체와 연결.&lt;/li&gt;
&lt;li&gt;런루프를 만드는 등 실행에 필요한 준비를 마무리함.&lt;/li&gt;
&lt;li&gt;실행 완료를 앞두고, 앱 객체가 앱 델리게이트에게 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;application:didFinishLaunchingWithOptions:&lt;/span&gt; 메시지를 보냄.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2021-07-06 오후 11.28.14.png&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TORTv/btq8UOeoTTl/vsw4xXs1JL9BdPYniGiIxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TORTv/btq8UOeoTTl/vsw4xXs1JL9BdPYniGiIxK/img.png&quot; data-alt=&quot;Objective-C 기반 iOS 프로젝트 main.m 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TORTv/btq8UOeoTTl/vsw4xXs1JL9BdPYniGiIxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTORTv%2Fbtq8UOeoTTl%2Fvsw4xXs1JL9BdPYniGiIxK%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;700&quot; height=&quot;150&quot; data-filename=&quot;스크린샷 2021-07-06 오후 11.28.14.png&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Objective-C 기반 iOS 프로젝트 main.m 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&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;UIApplicationMain 함수: &lt;u&gt;앱 로딩 프로세스&lt;/u&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2021-07-05 오후 11.41.13.png&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7ftaz/btq8UQauLn6/4VLCvPZz89wnlKWNLKRSdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7ftaz/btq8UQauLn6/4VLCvPZz89wnlKWNLKRSdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7ftaz/btq8UQauLn6/4VLCvPZz89wnlKWNLKRSdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7ftaz%2Fbtq8UQauLn6%2F4VLCvPZz89wnlKWNLKRSdk%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;700&quot; height=&quot;385&quot; data-filename=&quot;스크린샷 2021-07-05 오후 11.41.13.png&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파라미터&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;principalClassName: 앱 객체가 될 클래스 이름. nil이면 UIApplication으로 대체&lt;/li&gt;
&lt;li&gt;appDelegateClassName: 앱 델리게이트 클래스 이름.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기능&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;앱의 본체에 해당하는 객체인 UIApplication 객체 생성, 이 객체는 앱의 Life Cycle 관리&lt;/li&gt;
&lt;li&gt;지정된 클래스(@UIApplicationMain이 표시된)에서 델리게이트를 인스턴스화 하고 이를 앱의 객체에 할당&lt;/li&gt;
&lt;li&gt;앱의 Run Loop를 포함한 기본 이벤트처리 루프를 설정하고 이벤트 처리 시작&lt;/li&gt;
&lt;li&gt;앱의 info.plist에 불러올 main nib 파일이 명시되어있으면, 해당 nib 파일을 불러옴.&lt;/li&gt;
&lt;/ul&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;이제 @main에 대해 알아보자.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Swift 기반으로된 iOS 프로젝트는 main 파일이 없다. 그이유는?&lt;br /&gt;&lt;u&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;@main&lt;/span&gt;을 선언하여 iOS 앱의 진입점을 컴파일러가 합성하기 때문.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@main을&amp;nbsp;선언해줌으로써,&amp;nbsp;UIKit&amp;nbsp;앱의&amp;nbsp;진입점은 해당 클래스이고,&amp;nbsp;시스템은&amp;nbsp;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;UIApplicationDelegate&lt;/span&gt;&amp;nbsp;프로토콜에&amp;nbsp;구현되어있는&amp;nbsp;정적&amp;nbsp;main()&amp;nbsp;함수를&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-filename=&quot;xcode-4-2-app-launch-sequence.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCj8Xl/btq8ZiFw7Yn/Ye8sVsjwOYrA60vcvJuljk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCj8Xl/btq8ZiFw7Yn/Ye8sVsjwOYrA60vcvJuljk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCj8Xl/btq8ZiFw7Yn/Ye8sVsjwOYrA60vcvJuljk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCj8Xl%2Fbtq8ZiFw7Yn%2FYe8sVsjwOYrA60vcvJuljk%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;700&quot; height=&quot;394&quot; data-filename=&quot;xcode-4-2-app-launch-sequence.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(추가) Swift 5.3부터 프로그램의 entry point를 알려주는 속성이 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;@UIApplicationMain&lt;/span&gt;에서 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;@main&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;Ref.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/1622933-uiapplicationmain&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/uikit/1622933-uiapplicationmain&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiapplicationdelegate/3656306-main&quot;&gt;https://developer.apple.com/documentation/uikit/uiapplicationdelegate/3656306-main&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://barosalki.tistory.com/entry/iOS-Swift-53-main-type기반의-프로그램-진입점&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://barosalki.tistory.com/entry/iOS-Swift-53-main-type기반의-프로그램-진입점&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://soooprmx.com/앱델리게이트-이해하기-ios앱-만들기-01/&quot;&gt;https://soooprmx.com/앱델리게이트-이해하기-ios앱-만들기-01/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hcn1519.github.io/articles/2017-09/ios_app_lifeCycle&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hcn1519.github.io/articles/2017-09/ios_app_lifeCycle&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #777777;&quot;&gt;&lt;a href=&quot;https://oleb.net/blog/2012/02/app-launch-sequence-ios-revisited/&quot;&gt;https://oleb.net/blog/2012/02/app-launch-sequence-ios-revisited/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://you9010.tistory.com/225&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://you9010.tistory.com/225&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>iOS/iOS 본질을 파헤치쟈</category>
      <category>@main</category>
      <category>@UIApplicationMain</category>
      <category>iOS main</category>
      <category>iOS 애플리케이션 실행 순서</category>
      <category>UIApplicationMain</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/321</guid>
      <comments>https://you9010.tistory.com/321#entry321comment</comments>
      <pubDate>Tue, 6 Jul 2021 00:04:55 +0900</pubDate>
    </item>
    <item>
      <title>[개념 정리] Functional / Reative 개념은 왜 탄생했을까?</title>
      <link>https://you9010.tistory.com/306</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;아래 내용은 let us: Go! 2017 '&lt;a href=&quot;https://iamchiwon.github.io/2017/11/04/frpp/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Functional Reactive Programming 패러다임&lt;/a&gt;' 발표 내용을 정리한 글입니다.&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&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 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;Contents&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Programming&lt;/li&gt;
&lt;li&gt;Paradigm (패러다임)&lt;/li&gt;
&lt;li&gt;Functional&lt;br /&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;1)&amp;nbsp;Immutable&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2)&amp;nbsp;Pure&amp;nbsp;function&amp;nbsp;(순수&amp;nbsp;함수)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;3)&amp;nbsp;Generator,&amp;nbsp;Function,&amp;nbsp;Consumer,&amp;nbsp;Composition&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;4)&amp;nbsp;High-Order&amp;nbsp;function,&amp;nbsp;First&amp;nbsp;Class&amp;nbsp;Citizen&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;5)&amp;nbsp;Imperative&amp;nbsp;Programming(명령형&amp;nbsp;프로그래밍)&amp;nbsp;vs&amp;nbsp;Declarative&amp;nbsp;Programming(선언형&amp;nbsp;프로그래밍)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Reactive&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;Summary&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;b&gt;Functional&lt;/b&gt;: (Concurrent 시대에 여러 프로그램이 동시에 돌아가기 위해서 외부에 영향을 주지 않아야 하기 때문에 )&lt;br /&gt;Side-Effect가 없도록 프로그래밍 하는 패러다임&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Reative&lt;/b&gt;:&lt;br /&gt;Async한 작업을 Functional하게 처리하는 아이디어&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RxSwift&lt;/b&gt;:&lt;br /&gt;Reactive 아이디어를 구현한 Swift 라이브러리&lt;/li&gt;
&lt;/ul&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;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Programming&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 1.19.56.png&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;404&quot; width=&quot;600&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhe8VW/btqCB9mO4Ld/9kjomVtV1Ybi06brmqCl5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhe8VW/btqCB9mO4Ld/9kjomVtV1Ybi06brmqCl5k/img.png&quot; data-alt=&quot;Input으로 Output을 만드는 것, Output을 만드는 과정을 프로그래밍&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhe8VW/btqCB9mO4Ld/9kjomVtV1Ybi06brmqCl5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdhe8VW%2FbtqCB9mO4Ld%2F9kjomVtV1Ybi06brmqCl5k%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 1.19.56.png&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;404&quot; width=&quot;600&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Input으로 Output을 만드는 것, Output을 만드는 과정을 프로그래밍&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Paradigm(패러다임)&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;정의&lt;/b&gt;&lt;br /&gt;어떤 한 시대 사람들이 견해나 사고를 근본적으로 규정하고 있는 테두리로서의 인식의 체계, 또는 사물에 대한 이론적인 틀이나 체계를 의미하는 개념 (by 위키백과)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;(동시대를 살아가고 있는 사람들이 같은 생각을 가지고 있는 것 - &lt;u&gt;그 시대를 반영함&lt;/u&gt;)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 171px;&quot; border=&quot;1&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 8.062015503875969%; height: 19px;&quot;&gt;&lt;b&gt;시대&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.596899224806204%; height: 19px;&quot;&gt;&lt;b&gt;Low Memory&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 31.240310077519386%; height: 19px;&quot;&gt;&lt;b&gt;Mass Production&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.100775193798455%; height: 19px;&quot;&gt;&lt;b&gt;Concurrency&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 57px;&quot;&gt;
&lt;td style=&quot;width: 8.062015503875969%; height: 57px;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.596899224806204%; height: 57px;&quot;&gt;Low Memory&lt;br /&gt;Optimized&lt;br /&gt;Data : Program = 1 : 1&lt;/td&gt;
&lt;td style=&quot;width: 31.240310077519386%; height: 57px;&quot;&gt;Medium Memory&lt;br /&gt;Resuable&lt;br /&gt;Abstract Data&lt;/td&gt;
&lt;td style=&quot;width: 38.100775193798455%; height: 57px;&quot;&gt;High Memory&lt;br /&gt;Performance / Responsibility&lt;br /&gt;Concurrency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 95px;&quot;&gt;
&lt;td style=&quot;width: 8.062015503875969%; height: 95px;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.596899224806204%; height: 95px;&quot;&gt;- 최적화가 목표&lt;/td&gt;
&lt;td style=&quot;width: 31.240310077519386%; height: 95px;&quot;&gt;- 프로그래밍 대량 생산해야 하는 시대&lt;br /&gt;- 데이터 처리 재사용성을 높이는 방법과 클래스화, 추상화를 하여 재사용성을 높이는 새로운 패러다임이 생김&lt;/td&gt;
&lt;td style=&quot;width: 38.100775193798455%; height: 95px;&quot;&gt;- 동시에 여러개인 프로그램이 실행되야 하는 시대&amp;nbsp;&lt;br /&gt;: 프로그램이 동시에 여러 인스턴스로 실행됨&lt;br /&gt;- 프로그램이 다른 프로그램의 영향을 주면 안됨&lt;br /&gt;: Performance, 신뢰성 중요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Functional&lt;/h2&gt;
&lt;p&gt;Immutable,&amp;nbsp;Pure&amp;nbsp;function,&amp;nbsp;Composition,&amp;nbsp;High-Order&amp;nbsp;function,&amp;nbsp;first&amp;nbsp;class&amp;nbsp;citizen 등 이와 같은 용어가 왜 생겨나게 되었는지 살펴보자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) Immutable&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;u&gt;데이터 공유에 대한 문제점을 해결하고자 값을 쓰지 못하게 하는 Immutable 용어 등장&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Concurrency 시대에서 데이터를 여러 프로그램(인스턴스)이 동시에 읽고 쓰는 문제가 생김. (Read는 문제가 없지만 Write에 문제가 있음)
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;전 시대에는 synchronize를 걸고, 세마포어나 뮤텍스를 사용하여 동기화를 맞추는 방법으로 해결함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;요즘 modern language들은 못쓰는 변수 제공 : &quot;&lt;u&gt;&lt;b&gt;Immutable&lt;/b&gt;&lt;/u&gt;&quot; (ex. Swift Langauge의 let)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;992&quot; data-filename=&quot;blob&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PCQ5j/btqCEN4r5cG/VLXkRILLTcvNxgi46dDOik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PCQ5j/btqCEN4r5cG/VLXkRILLTcvNxgi46dDOik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PCQ5j/btqCEN4r5cG/VLXkRILLTcvNxgi46dDOik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPCQ5j%2FbtqCEN4r5cG%2FVLXkRILLTcvNxgi46dDOik%2Fimg.png&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;992&quot; data-filename=&quot;blob&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2)&amp;nbsp;Pure function (순수 함수)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pure function(순수 함수): &lt;span style=&quot;background-color: #f6e199;&quot;&gt;외부 변수를 사용하지 않고 파라미터로 값을 만들고 새로운 값을 리턴하는 함수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;배경: Concurrency 시대에 값을 공유함으로써 Side-Effect가 생김 (외부 변수에 문제가 생기기 때문에 Side-Effect라고 부름)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;u&gt;&lt;b&gt;결론&lt;/b&gt;: 순수함수를 사용하자.&lt;/u&gt; (high memory 시대니까 메모리는 걱정 없으니까 side-effect를 줄이기 위해서)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 11.37.58.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;950&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mGKHb/btqCGQM2qnT/hRfHxfmO40kx27KjNyAvDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mGKHb/btqCGQM2qnT/hRfHxfmO40kx27KjNyAvDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mGKHb/btqCGQM2qnT/hRfHxfmO40kx27KjNyAvDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmGKHb%2FbtqCGQM2qnT%2FhRfHxfmO40kx27KjNyAvDk%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 11.37.58.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;950&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3)&amp;nbsp;Generator, Function, Consumer, Composition&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수 종류의 용어 정리
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Generator&lt;/b&gt;&lt;/span&gt;: Output만 존재하는 함수&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Function&lt;/b&gt;&lt;/span&gt;: Input, Output이 존재하는 함수&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Consumer&lt;/b&gt;&lt;/span&gt;: Input만 존재하는 함수&lt;/li&gt;
&lt;li&gt;(Ref. Submodule, Action: Input, Output이 없는 함수)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Composition&lt;/span&gt; (함수의 합성)&amp;nbsp;&lt;/b&gt;: 함수와 함수를 섞어서 사용하는 것을 뜻함.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 1.52.55.png&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;896&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lJUsP/btqCD9fC1pF/xReRFyaL0EuUCPA9kfiP31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lJUsP/btqCD9fC1pF/xReRFyaL0EuUCPA9kfiP31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lJUsP/btqCD9fC1pF/xReRFyaL0EuUCPA9kfiP31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlJUsP%2FbtqCD9fC1pF%2FxReRFyaL0EuUCPA9kfiP31%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 1.52.55.png&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;896&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4)&amp;nbsp;High-Order function,&amp;nbsp;First Class Citizen&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;High-Order function (고차 함수)&lt;/span&gt;:&lt;br /&gt;함수가 파라미터로 전달되는 될 때, 함수 안에서 함수가 사용되는 것이 2개면 2차 함수, 3개면 3차함수, 여러개면 고차함수.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;First Class Citizen (일급 개체)&lt;/span&gt;:&lt;br /&gt;변수에 담거나 리턴값으로 사용할 수 있거나, Array에 담을 수 있는 것을 일급 개체라고 함.&lt;/li&gt;
&lt;li&gt;Funtional Language: Function 자체를 일급 개체화 할 수 있는 언어&lt;/li&gt;
&lt;li&gt;Swift는 &lt;u&gt;Multi-Paradigm Language&lt;/u&gt; : Function, Protocol, Struct를 일급개체화 할 수 있으므로.&lt;br /&gt;(Ref. 자바는 Object를 일급개체화 하므로 OOP)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 1.57.51.png&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;948&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/opx4X/btqCGQszU31/gMtoWJuBpRKtP95XMGxtM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/opx4X/btqCGQszU31/gMtoWJuBpRKtP95XMGxtM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/opx4X/btqCGQszU31/gMtoWJuBpRKtP95XMGxtM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fopx4X%2FbtqCGQszU31%2FgMtoWJuBpRKtP95XMGxtM0%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 1.57.51.png&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;948&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;5) Imperative Programming(명령형 프로그래밍) vs&amp;nbsp;Declarative Programming(선언형 프로그래밍)&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 2.01.01.png&quot; data-origin-width=&quot;1286&quot; data-origin-height=&quot;804&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8kyqh/btqCEO3qo8x/zkgeqtN0oolMxrWY5ujkCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8kyqh/btqCEO3qo8x/zkgeqtN0oolMxrWY5ujkCK/img.png&quot; data-alt=&quot;데이터를 정의하고 그것의 변화 과정을 프로그래밍 할 것이냐, 행위를 정의하고 거기에 데이터를 넣을 것이냐의 차이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8kyqh/btqCEO3qo8x/zkgeqtN0oolMxrWY5ujkCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8kyqh%2FbtqCEO3qo8x%2FzkgeqtN0oolMxrWY5ujkCK%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 2.01.01.png&quot; data-origin-width=&quot;1286&quot; data-origin-height=&quot;804&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터를 정의하고 그것의 변화 과정을 프로그래밍 할 것이냐, 행위를 정의하고 거기에 데이터를 넣을 것이냐의 차이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특별한 기술이 아니고 기존에 있던 방식으로 function 방식으로 프로그래밍을 하면 Functional Programming인 것.&lt;/li&gt;
&lt;li&gt;생각의 주체를 데이터에 두느냐 함수에 두드냐 생각의 관점이 옮겨짐 =&amp;gt; 패러다임&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;6) &lt;/b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;'Functional' Summary&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터는 immutable하게 취급하자&lt;/li&gt;
&lt;li&gt;데이터 변경이 필요할 때는 새로 만들자&lt;/li&gt;
&lt;li&gt;Side-Effect를 없애기 위해서 Pure function을 사용하자&lt;/li&gt;
&lt;li&gt;Function들의 Composition과 High-Order Function으로 프로그램을 만들자&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Data가 아닌 Process에 집중해서 프로그램을 만들자&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Reactive&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Async job, Expensive job : Callback or Delegate pattern으로 주로 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;u&gt;배경: Async한 상황에서 async한 데이터를 어떻게 처리할 것이냐! 로 개념이 나오게 됨.&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;결론: 스트림을 만들고 거기에 데이터를 흘려보내자,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Reactive 정의&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In computing, reactive programming is an &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;asynchronous&lt;/b&gt;&lt;/span&gt; programming paradigm concerned with&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;b&gt;data streams&lt;/b&gt;&lt;/span&gt; and the propagation of change.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 2.12.29.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;770&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEIJS4/btqCB7P3p8M/NB7cUkHETZB5EZPP2n50T1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEIJS4/btqCB7P3p8M/NB7cUkHETZB5EZPP2n50T1/img.png&quot; data-alt=&quot;Observable은 데이터를 만드는 타입. 데이터가 흘러가는 사이에 Operator를 통해서 데이터를 변형 또는 조작이 이루어짐.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEIJS4/btqCB7P3p8M/NB7cUkHETZB5EZPP2n50T1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEIJS4%2FbtqCB7P3p8M%2FNB7cUkHETZB5EZPP2n50T1%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 2.12.29.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;770&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Observable은 데이터를 만드는 타입. 데이터가 흘러가는 사이에 Operator를 통해서 데이터를 변형 또는 조작이 이루어짐.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-12 오전 2.12.51.png&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;738&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXlApD/btqCD9NrX3H/KRLav532g9D5kznfVdkkN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXlApD/btqCD9NrX3H/KRLav532g9D5kznfVdkkN0/img.png&quot; data-alt=&quot;getText에 url을 넣으면 Stream을 리턴하는 것. 통신을 마치고 데이터를 스트림을 통해서 원하는 곳에 전달이 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXlApD/btqCD9NrX3H/KRLav532g9D5kznfVdkkN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXlApD%2FbtqCD9NrX3H%2FKRLav532g9D5kznfVdkkN0%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-12 오전 2.12.51.png&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;738&quot; width=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;getText에 url을 넣으면 Stream을 리턴하는 것. 통신을 마치고 데이터를 스트림을 통해서 원하는 곳에 전달이 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;Reactive Summary&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Async한 처리를 Functional하게 처리하자&lt;/li&gt;
&lt;li&gt;리턴값은 Stream인 Observable을 반환하자&lt;/li&gt;
&lt;li&gt;Stream에 흐르는 Data/Event를 Operator로 처리하자&lt;/li&gt;
&lt;li&gt;Stream과 Stream을 연결하자&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Data가 아닌 Process에 집중해서 프로그램을 만들자&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ref.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;a href=&quot;https://iamchiwon.github.io/2017/11/04/frpp/&quot;&gt;https://iamchiwon.github.io/2017/11/04/frpp/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1583944376235&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Functional Reactive Programming Paradigm&quot; data-og-description=&quot;let us: Go! 2017 가을 세미나에서 발표한 내용&quot; data-og-host=&quot;iamchiwon.github.io&quot; data-og-source-url=&quot;https://iamchiwon.github.io/2017/11/04/frpp/&quot; data-og-url=&quot;https://iamchiwon.github.io/2017/11/04/frpp/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://iamchiwon.github.io/2017/11/04/frpp/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://iamchiwon.github.io/2017/11/04/frpp/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Functional Reactive Programming Paradigm&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;let us: Go! 2017 가을 세미나에서 발표한 내용&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;iamchiwon.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Functional Thinking</category>
      <category>function composition</category>
      <category>funtional</category>
      <category>immutable</category>
      <category>pure function</category>
      <category>Reactive 프로그래밍</category>
      <category>고차함수</category>
      <category>순수 함수</category>
      <category>패러다임</category>
      <category>함수의 합성</category>
      <category>함수형 프로그래밍이란</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/306</guid>
      <comments>https://you9010.tistory.com/306#entry306comment</comments>
      <pubDate>Thu, 12 Mar 2020 02:22:39 +0900</pubDate>
    </item>
    <item>
      <title>[Git] 커밋 메시지 수정하기 - git rebase</title>
      <link>https://you9010.tistory.com/302</link>
      <description>&lt;p&gt;예전에 커밋한 메시지를 수정하는 방법을 알아보자&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. 수정을 원하는 커밋이 존재하는 곳까지 HEAD로 부터 지정&lt;/p&gt;
&lt;pre id=&quot;code_1583457564040&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git rebase -i HEAD~5&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러면 아래와 같이 편집을 할 수 있는데, 수정을 원하는 커밋에 pick 대신 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;edit(또는 e)&lt;/span&gt;를 써준다! &lt;br /&gt;(커밋 메시지 수정 외의 다른 기능도 있음 - 아래 명령어 참조)&lt;/p&gt;
&lt;pre id=&quot;code_1583457720908&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pick cc5605d test1
e 487bd6b test2
e 73bda22 test3
pick 0ce101f test4
pick a2198fc test5

# Rebase bb0d4f2..a2198fc onto bb0d4f2 (5 commands)
#
# Commands:
# p, pick &amp;lt;commit&amp;gt; = use commit
# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message
# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending
# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit
# f, fixup &amp;lt;commit&amp;gt; = like &quot;squash&quot;, but discard this commit's log message
# x, exec &amp;lt;command&amp;gt; = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop &amp;lt;commit&amp;gt; = remove commit
# l, label &amp;lt;label&amp;gt; = label current HEAD with a name
# t, reset &amp;lt;label&amp;gt; = reset HEAD to a label
# m, merge [-C &amp;lt;commit&amp;gt; | -c &amp;lt;commit&amp;gt;] &amp;lt;label&amp;gt; [# &amp;lt;oneline&amp;gt;]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c &amp;lt;commit&amp;gt; to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2. 위 vi를 수정하고 저장하면 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;edit(또는 e)&lt;/span&gt;로 지정한 커밋 메시지로 차례차례 옮겨진다.&lt;/p&gt;
&lt;p&gt;아래 명령어를 입력하여 현재 위치에 있는 메시지 수정&lt;/p&gt;
&lt;pre id=&quot;code_1583457882912&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git commit -amend&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;수정이 완료가 되었으면 아래 명령어 입력. 아래 명령어를 입력하면 다음 수정하는 커밋으로 HEAD가 이동된다.&lt;/p&gt;
&lt;pre id=&quot;code_1583457914244&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git rebase --continue&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;수정을 원하는 커밋이 모두 수정 완료되면&lt;/p&gt;
&lt;pre id=&quot;code_1583457992346&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Successfully rebased and updated refs/heads/branch_name.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 나오면 정상적으로 수정 끝!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git</category>
      <category>Git</category>
      <category>git rebase</category>
      <category>커밋 메시지 수정</category>
      <category>커밋 수정</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/302</guid>
      <comments>https://you9010.tistory.com/302#entry302comment</comments>
      <pubDate>Fri, 6 Mar 2020 10:29:04 +0900</pubDate>
    </item>
    <item>
      <title>[Swift 5.2] Subscripts - Apple Documentation</title>
      <link>https://you9010.tistory.com/299</link>
      <description>&lt;p style=&quot;text-align: left; font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;목차&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;text-align: left; font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-size: 16px; letter-spacing: 0px;&quot;&gt;Subscript Syntax&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: left; font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-size: 16px; letter-spacing: 0px;&quot;&gt;Subscript Usage&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: left; font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-size: 16px; letter-spacing: 0px;&quot;&gt;Type Subscripts&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot;&gt;&lt;span&gt;Subscripts&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Classes, structures, and enumerations&lt;/span&gt; can define&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;subscripts&lt;span style=&quot;color: #333333;&quot;&gt;, which are&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;shortcuts&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;for accessing the member elements&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;of a collection, list, or sequence&lt;/u&gt;.&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;(subscript - &lt;span style=&quot;color: #333333;&quot;&gt;컬렉션, 리스트, 시퀀스의 멤버 엘리먼트에 접근하기 위한 shortcut을 제공)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;ex) someArray[index], someDictionary[key], ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1. Subscript Syntax&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- subscripts can be read-write or read-only.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1583399387399&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background-color: #f6f7f8; font-size: 14px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;subscript(index: Int) -&amp;gt; Int {
    get {
        // Return an appropriate subscript value here.
    }
    set(newValue) {
        // Perform a suitable setting action here.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Subscript Usage&lt;/h4&gt;
&lt;pre id=&quot;code_1583399387399&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background-color: #f6f7f8; font-size: 14px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: 0.0, count: rows * columns)
    }
    func indexIsValid(row: Int, column: Int) -&amp;gt; Bool {
        return row &amp;gt;= 0 &amp;amp;&amp;amp; row &amp;lt; rows &amp;amp;&amp;amp; column &amp;gt;= 0 &amp;amp;&amp;amp; column &amp;lt; columns
    }
    subscript(row: Int, column: Int) -&amp;gt; Double {
        get {
            assert(indexIsValid(row: row, column: column), &quot;Index out of range&quot;)
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), &quot;Index out of range&quot;)
            grid[(row * columns) + column] = newValue
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3. Type Subscripts&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1583399387400&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background-color: #f6f7f8; font-size: 14px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
    static subscript(n: Int) -&amp;gt; Planet {
        return Planet(rawValue: n)!
    }
}
let mars = Planet[4]
print(mars)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ref.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html&quot;&gt;https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kka7.tistory.com/118?category=919617&quot;&gt;https://kka7.tistory.com/118?category=919617&lt;/a&gt;&lt;/p&gt;</description>
      <category>iOS/Swift</category>
      <category>Subscripts</category>
      <category>swift basic</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/299</guid>
      <comments>https://you9010.tistory.com/299#entry299comment</comments>
      <pubDate>Thu, 5 Mar 2020 18:15:47 +0900</pubDate>
    </item>
    <item>
      <title>[Swift 5.2] Methods - Apple Documentation</title>
      <link>https://you9010.tistory.com/298</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot;&gt;Methods&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;
&lt;li&gt;Instance Method&lt;/li&gt;
&lt;li&gt;Type Method&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Class, Structure, Enumeration 모두 생성 가능&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Instance Method&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;Modifying Value Types from Within Instance Methods&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본적으로, Value 타입의 property는 인스턴스 메소드 안에서 수정될 수 없음.&amp;nbsp; (여기서말하는 value 타입은 struct, enum)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;mutating&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;키워드 : 메소드에서 property의 수정이 가능하도록 정의하기 위해 추가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1583398734555&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background-color: #f6f7f8; font-size: 14px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print(&quot;The point is now at (\(somePoint.x), \(somePoint.y))&quot;)
// Prints &quot;The point is now at (3.0, 4.0)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Type Method&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;타입 자체에서 호출되는 메소드&lt;/li&gt;
&lt;li&gt;func 키워드 앞에 static 키워드 작성&lt;/li&gt;
&lt;li&gt;Objective-C에서는 Class에서만 type-level method를 정의할 수 있었다. Swift에서는 모든 클래스, 구조체, 열거형에서 정의 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1583398734556&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background-color: #f6f7f8; font-size: 14px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1583398734556&quot; class=&quot;swift&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background-color: #f6f7f8; font-size: 14px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct LevelTracker {
    static var highestUnlockedLevel = 1
    var currentLevel = 1

    static func unlock(_ level: Int) {
        if level &amp;gt; highestUnlockedLevel { highestUnlockedLevel = level }
    }

    static func isUnlocked(_ level: Int) -&amp;gt; Bool {
        return level &amp;lt;= highestUnlockedLevel
    }

    @discardableResult
    mutating func advance(to level: Int) -&amp;gt; Bool {
        if LevelTracker.isUnlocked(level) {
            currentLevel = level
            return true
        } else {
            return false
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ref.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/Methods.html&quot;&gt;https://docs.swift.org/swift-book/LanguageGuide/Methods.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kka7.tistory.com/117?category=919617&quot;&gt;https://kka7.tistory.com/117?category=919617&lt;/a&gt;&lt;/p&gt;</description>
      <category>iOS/Swift</category>
      <category>mutating</category>
      <category>SWIFT</category>
      <category>swift static</category>
      <category>type method</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/298</guid>
      <comments>https://you9010.tistory.com/298#entry298comment</comments>
      <pubDate>Thu, 5 Mar 2020 18:08:14 +0900</pubDate>
    </item>
    <item>
      <title>[Swift] ExpressibleByStringLiteral, CustomStringConvertible</title>
      <link>https://you9010.tistory.com/291</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swift/expressiblebystringliteral&quot;&gt;https://developer.apple.com/documentation/swift/expressiblebystringliteral&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1582015355037&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swift/expressiblebystringliteral&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;position: relative; border-right-width: 1px; border-right-style: solid; border-right-color: #d9d9d9; width: 200px; height: 200px; background-size: cover; background-image: url('https://you9010.tistory.com/manage/newpost/?type=post&amp;amp;returnURL=%2Fmanage%2Fposts%2F'); background-position: center center;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot; style=&quot;position: relative; flex-grow: 1; height: 130px; padding-left: 40px;&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;line-height: 1.6; color: #000000; font-size: 22px; padding-bottom: 10px; max-width: 467px; text-overflow: ellipsis; white-space: nowrap; margin: 0px; overflow: hidden; font-family: 'Noto Sans', 'Noto Sans KR';&quot;&gt;ExpressibleByStringLiteral - Swift Standard Library | Apple Developer Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;line-height: normal; margin: 0px; max-width: 467px; text-overflow: ellipsis; overflow: hidden; font-family: 'Noto Sans DemiLight', sans-serif; font-size: 14px; font-weight: 300; font-style: normal; font-stretch: normal; letter-spacing: normal; color: #909090; max-height: 42px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; display: -webkit-box;&quot;&gt;Protocol ExpressibleByStringLiteral A type that can be initialized with a string literal. Declarationprotocol ExpressibleByStringLiteral OverviewThe String and StaticString types conform to the ExpressibleByStringLiteral protocol. You can initialize a vari&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;line-height: 1.6; margin: 0px; position: absolute; bottom: -8px; font-family: AvenirNext; font-size: 14px; color: #909090;&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;The&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;StaticString&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;types conform to the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;ExpressibleByStringLiteral&lt;/span&gt;protocol. You can initialize a variable or constant of either of these types using a string literal of any length.&lt;/p&gt;
&lt;h3 id=&quot;2848729&quot;&gt;Conforming to ExpressibleByStringLiteral&lt;/h3&gt;
&lt;p&gt;To add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;ExpressibleByStringLiteral&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;conformance to your custom type, implement the required initializer.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swift/customstringconvertible&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/swift/customstringconvertible&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1582015419348&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CustomStringConvertible - Swift Standard Library | Apple Developer Documentation&quot; data-og-description=&quot;Types that conform to the CustomStringConvertible protocol can provide their own representation to be used when converting an instance to a string. The String(describing:) initializer is the preferred way to convert an instance of any type to a string. If &quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/documentation/swift/customstringconvertible&quot; data-og-url=&quot;https://developer.apple.com/documentation/swift/customstringconvertible&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swift/customstringconvertible&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/documentation/swift/customstringconvertible&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;CustomStringConvertible - Swift Standard Library | Apple Developer Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Types that conform to the CustomStringConvertible protocol can provide their own representation to be used when converting an instance to a string. The String(describing:) initializer is the preferred way to convert an instance of any type to a string. If&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;Types that conform to the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;CustomStringConvertible&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;protocol &lt;u&gt;can provide their own representation to be used when converting an instance to a string&lt;/u&gt;. The&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;String(describing:)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;initializer is the preferred way to convert an instance of&lt;span&gt;&amp;nbsp;&lt;/span&gt;any&lt;span&gt;&amp;nbsp;&lt;/span&gt;type to a string. If the passed instance conforms to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;CustomStringConvertible&lt;/span&gt;, the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;String(describing:)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;initializer and the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;print(_:)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;function use the instance&amp;rsquo;s custom&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;property.&lt;/p&gt;
&lt;p&gt;Accessing a type&amp;rsquo;s&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;property directly or using&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;CustomStringConvertible&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;as a generic constraint is discouraged.&lt;/p&gt;
&lt;h3 id=&quot;2844984&quot;&gt;Conforming to the CustomStringConvertible Protocol&lt;/h3&gt;
&lt;p&gt;Add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;CustomStringConvertible&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;conformance to your custom types by defining a&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;property.&lt;/p&gt;
&lt;p&gt;For example, this custom&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Point&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;struct uses the default representation supplied by the standard library:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Example&lt;/h2&gt;
&lt;pre id=&quot;code_1582015282986&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum CompassPoint {
    case north
    case south
	case custom(String)
}

extension CompassPoint: ExpressibleByStringLiteral {
	init(stringLiteral value: String) {
        switch value {
        case &quot;north&quot;:
            self = .north
        case &quot;south&quot;:
            self = .south
		default:
        	self = .custom(value)
		}
	}
}

extension CompassPoint: CustomStringConvertible {
	public var description: String {
        switch self {
        case .north:
	        return &quot;north&quot;
        case .south:
        	return &quot;south&quot;
        case .custom(let type):
            return type
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>iOS/Swift</category>
      <category>CustomStringConvertible</category>
      <category>ExpressibleByStringLiteral</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/291</guid>
      <comments>https://you9010.tistory.com/291#entry291comment</comments>
      <pubDate>Tue, 18 Feb 2020 17:45:12 +0900</pubDate>
    </item>
    <item>
      <title>[Swift] ReactorKit 개념과 사용 방법</title>
      <link>https://you9010.tistory.com/289</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-02-09 오전 3.33.39.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;666&quot; width=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRXKUf/btqBSNQ2bbl/fUvyF37MQHZkGcjZ2XZ0c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRXKUf/btqBSNQ2bbl/fUvyF37MQHZkGcjZ2XZ0c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRXKUf/btqBSNQ2bbl/fUvyF37MQHZkGcjZ2XZ0c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRXKUf%2FbtqBSNQ2bbl%2FfUvyF37MQHZkGcjZ2XZ0c0%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-02-09 오전 3.33.39.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;666&quot; width=&quot;500&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;
&lt;li&gt;Basic Concept&lt;/li&gt;
&lt;li&gt;View&lt;br /&gt;1) 뷰 정의하기&lt;br /&gt;2) bind(reactor:) 이란?&lt;/li&gt;
&lt;li&gt;Reactor = ViewModel&lt;br /&gt;1) mutate()&lt;br /&gt;2) reduce()&lt;br /&gt;3) transform()&lt;/li&gt;
&lt;li&gt;Advanced&lt;br /&gt;- Global States&lt;br /&gt;- View Comminucation&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Basic Concept&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;ReactorKit is a combination of&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://facebook.github.io/flux/&quot;&gt;Flux&lt;/a&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Reactive_programming&quot;&gt;Reactive Programming&lt;/a&gt;&lt;span&gt;. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;유저의 액션과 뷰 상태는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;observable stream&lt;/span&gt;을 통해 각 레이어로 전달됨&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;이 스트림들은 한방향이다: &lt;u&gt;뷰는 오직 액션만 방출할 수 있고 리액터는 상태만 방출할 수 있다&lt;/u&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. View&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;뷰는 데이터를 보여주는 역할.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;뷰는 사용자의 인풋을 액션스트림에 바인딩하고, 뷰 상태를 UI 컴포넌트에 바인딩함.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;1) 뷰 정의하기&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;뷰를 정의하기 위해서, 존재하는 클래스에 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;View&lt;/span&gt; 프로토콜을 컨펌시키자. 그러면 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;reactor&lt;/span&gt;라는 프로퍼티를 자동으로 가질 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이 프로퍼티는 일반적으로 view의 외부에 설정된다. (&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;뷰 외부에서 reator 주입시키는 것이 일반적&lt;/u&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1581184328531&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class ProfileViewController: UIViewController, View {
  var disposeBag = DisposeBag()
}

profileViewController.reactor = UserViewReactor() // inject reactor(reactor 주입)&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) bind(reactor:) 란?&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;뷰와 리엑터 사이의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;액션 스트림&lt;/span&gt;과 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;상태 스트림&lt;/span&gt;을 바인드하기 위한 메서드&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;reactor&lt;/span&gt; 프로퍼티가 변경되면, &lt;span style=&quot;background-color: #dddddd;&quot;&gt;bind(reacor:)가&lt;/span&gt; 호출된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1581184673563&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func bind(reactor: ProfileViewReactor) {
  // action (View -&amp;gt; Reactor)
  refreshButton.rx.tap.map { Reactor.Action.refresh }
    .bind(to: reactor.action)
    .disposed(by: self.disposeBag)

  // state (Reactor -&amp;gt; View)
  reactor.state.map { $0.isFollowing }
    .bind(to: followButton.rx.isSelected)
    .disposed(by: self.disposeBag)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;NOTE&lt;/b&gt;&lt;br /&gt;ReatorKit에서 말하는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;액션 스트림&lt;/span&gt;과 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;상태 스트림&lt;/span&gt;은 아래 Reactor 클래스의 구현부를 보면 알 수 있다.&lt;br /&gt;뷰에 있는 UI 컴포넌트에 rx를 이용하여 해당 Observable을 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;reactor의 action&lt;/span&gt;이 구독한다.&amp;nbsp;&lt;br /&gt;그리고, &lt;span style=&quot;background-color: #dddddd;&quot;&gt;reactor.state&lt;/span&gt;인 Observable을 뷰의 UI 컴포넌트가 구독한다.&lt;br /&gt;&lt;br /&gt;이와 같이 단방향으로 액션 스트림과 상태스트림으로 Action과 State 데이터가 이동한다.&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;888&quot; width=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BeTu4/btqCF6i0s76/QEH1EBZtYndIIT8hgLKFTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BeTu4/btqCF6i0s76/QEH1EBZtYndIIT8hgLKFTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BeTu4/btqCF6i0s76/QEH1EBZtYndIIT8hgLKFTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBeTu4%2FbtqCF6i0s76%2FQEH1EBZtYndIIT8hgLKFTK%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;888&quot; width=&quot;700&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Reactor = ViewModel&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;Reactor는 뷰의 상태를 관리하는 UI 독립적인 계층&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Reactor의 가장 중요한 역할은 뷰로부터 제어 흐름을 분리하는 것&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 뷰는 해당 Reacor를 가지고 있으며, 모든 로직을 그 Reactor에 위임한다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Reactor는 뷰의 의존성이 없기 때문에 테스트하기가 용이하다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;리엑터를 정의하기 위해서는 &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;Reactor&lt;/span&gt;&lt;/b&gt; 프로토콜을 준수하자!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;세개 타입&amp;nbsp;&lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;Action&lt;/span&gt;&lt;/b&gt;, &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;Mutation&lt;/span&gt;&lt;/b&gt;, &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;State&lt;/span&gt;&lt;/b&gt;. + &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;initialState&lt;/span&gt;&lt;/b&gt; 프로퍼티 필수!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Action은 사용자의 인터렉션, State는 뷰의 상태&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1581186906506&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class ProfileViewReactor: Reactor {
  // represent user actions (유저 액션을 나타냄)
  enum Action {
    case refreshFollowingStatus(Int)
    case follow(Int)
  }

  // represent state changes (상태 변화를 나타냄)
  enum Mutation {
    case setFollowing(Bool)
  }

  // represents the current view state (현재 뷰 상태를 나타냄)
  struct State {
    var isFollowing: Bool = false
  }

  let initialState: State = State()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(중요)&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;리엑터는 2단계로 액션 스트림을 상태 스트림으로 변경한다:&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;mutate()&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;reduce()&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-02-09 오전 3.43.05.png&quot; width=&quot;600&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TayKq/btqBOCckHOO/x8SLYmBkMErAT7xoQqOzE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TayKq/btqBOCckHOO/x8SLYmBkMErAT7xoQqOzE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TayKq/btqBOCckHOO/x8SLYmBkMErAT7xoQqOzE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTayKq%2FbtqBOCckHOO%2Fx8SLYmBkMErAT7xoQqOzE0%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-02-09 오전 3.43.05.png&quot; width=&quot;600&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;640&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) mutate()&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;View로부터 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Action&lt;/span&gt;을 받고, &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Observable&amp;lt;Mutation&amp;gt;&lt;/span&gt;을 생성한다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1581187507364&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func mutate(action: Action) -&amp;gt; Observable&amp;lt;Mutation&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;비동기 오퍼레이션 또는 API 호출과 같은 모든 사이드 이펙트는 이 메소드 안에서 수행된다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1581187654628&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func mutate(action: Action) -&amp;gt; Observable&amp;lt;Mutation&amp;gt; {
  switch action {
  case let .refreshFollowingStatus(userID): // receive an action
    return UserAPI.isFollowing(userID) // create an API stream
      .map { (isFollowing: Bool) -&amp;gt; Mutation in
        return Mutation.setFollowing(isFollowing) // convert to Mutation stream
      }

  case let .follow(userID):
    return UserAPI.follow()
      .map { _ -&amp;gt; Mutation in
        return Mutation.setFollowing(true)
      }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) reduce()&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;기존 State과 Mutation으로부터 새로운 State를 생성&lt;/p&gt;
&lt;pre id=&quot;code_1581188275455&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func reduce(state: State, mutation: Mutation) -&amp;gt; State&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;이 메소드는 순수함수(pure function)이므로 동기적으로 &lt;u&gt;새로운 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;State&lt;/span&gt;를 리턴&lt;/u&gt;해야한다. 이 함수안에서 어떤 side effect들을 수행하지 말자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1581188417381&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func reduce(state: State, mutation: Mutation) -&amp;gt; State {
	var state = state 	// create a copy of the old state
    switch mutation {
    case let .setFollowing(isFollowing):
    	state.isFollowing = isFollowing // manipulate the state, create a new state
        return state	// return the new state
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) transform()&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;transform()은 각 스트림을 변형한다. 세 transform() 함수가 존재한다:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1581188531671&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func transform(action: Observable&amp;lt;Action&amp;gt;) -&amp;gt; Observable&amp;lt;Action&amp;gt;
func transform(mutation: Observable&amp;lt;Mutation&amp;gt;) -&amp;gt; Observable&amp;lt;Mutation&amp;gt;
func transform(state: Observable&amp;lt;State&amp;gt;) -&amp;gt; Observable&amp;lt;State&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다른 observable 스트림을 결합하고 변경하려면 이 함수들을 구현하자.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를들어, transform(mutation:)은 global event stream을 mutation stream에 결합하기 위한 좋은 방법이다.&amp;nbsp;Global state는 아래에서 자세히 살펴보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 메소드는 디버깅을 위한 목적으로 사용될 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1581188646561&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func transform(action: Observable&amp;lt;Action&amp;gt;) -&amp;gt; Observable&amp;lt;Action&amp;gt; {
  return action.debug(&quot;action&quot;) // Use RxSwift's debug() operator
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Advanced&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Global States&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Reactor의 일반적 &lt;b&gt;Action &amp;rarr; Mutation &amp;rarr; State&amp;nbsp;&lt;/b&gt;흐름에 global state는 없으므로, global state 변경을 위해서 transform(muation:)을 사용해야 한다.&lt;/li&gt;
&lt;li&gt;예) 현재 인증된 유저들을 저장하는 global BehaviorSubject가 있다고 가정. 만약 currentUser가 변경되었을 때 Mutation.setUser(User?)를 방출하기를 원한다면 아래와 같이 작성. 그리고 그 mutation은 뷰가 액션을 리엑터에게 보낼 때 각 시간에 방출될 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1584281212178&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var currentUser: BehaviorSubject&amp;lt;User&amp;gt; // global state

func transform(mutation: Observable&amp;lt;Mutation&amp;gt;) -&amp;gt; Observable&amp;lt;Mutation&amp;gt; {
  return Observable.merge(mutation, currentUser.map(Mutation.setUser))
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;View Communication&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ReactorKit은 global app state를 정의하고 있지 않으므로, global state를 관리하기 위해서 BehaviorSubject, PublishSubject, reactor를 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;여러개의 뷰들을 커뮤니케이션하기 위해서는 callback 클로저나 delegate 패턴을 사용하는 것이 일반적.&lt;/li&gt;
&lt;li&gt;ReactorKit은 &lt;a href=&quot;https://github.com/ReactiveX/RxSwift/blob/master/RxSwift/Reactive.swift&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;reactive extension&lt;/a&gt;을 사용하는것을 추천한다.&lt;/li&gt;
&lt;li&gt;주요 목적은 커스텀한 뷰에 대한 커뮤니케이션을 해결하기 위한 것.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2020-03-15 오후 11.06.33.png&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;846&quot; width=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9Zyjt/btqCLMwWC99/6KtcBEAgiYEXpJQ3NejX41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9Zyjt/btqCLMwWC99/6KtcBEAgiYEXpJQ3NejX41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9Zyjt/btqCLMwWC99/6KtcBEAgiYEXpJQ3NejX41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9Zyjt%2FbtqCLMwWC99%2F6KtcBEAgiYEXpJQ3NejX41%2Fimg.png&quot; data-filename=&quot;스크린샷 2020-03-15 오후 11.06.33.png&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;846&quot; width=&quot;500&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;예) ChatViewController는 메시지를 보여주는 뷰컨트롤러. ChatViewController는 MessageInputView를 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;유저가 MessageInputView의 보내기 버튼을 탭하면, 그 텍스트는 ChatViewController에 보내질 것이고, ChatViewController는 리엑터의 액션과 바인드될 것이다. MessageView의 reactor extension의 예이다:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1584281504768&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;extension Reactive where Base: MessageInputView {
  var sendButtonTap: ControlEvent&amp;lt;String&amp;gt; {
    let source = base.sendButton.rx.tap.withLatestFrom(...)
    return ControlEvent(events: source)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;ChatViewController에서 messageinputView extension를 아래와 같이 사용하자:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1584281520908&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;messageInputView.rx.sendButtonTap
  .map(Reactor.Action.send)
  .bind(to: reactor.action)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ref.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ReactorKit/ReactorKit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ReactorKit/ReactorKit&lt;/a&gt;&lt;/p&gt;</description>
      <category>iOS/ReactorKit</category>
      <category>ReacotKit</category>
      <category>Reactor global state</category>
      <category>Reactor View Communication</category>
      <category>Reactor란</category>
      <category>Swift Reator</category>
      <author>you90100</author>
      <guid isPermaLink="true">https://you9010.tistory.com/289</guid>
      <comments>https://you9010.tistory.com/289#entry289comment</comments>
      <pubDate>Sun, 9 Feb 2020 04:31:35 +0900</pubDate>
    </item>
  </channel>
</rss>