ios개발/함수형 프로그래밍

<함수형 프로그래밍> 5편 Functional Reactive Programming Intro by Mike Bopp

studying develop 2020. 4. 19. 17:19

[https://www.rapiddg.com/article/functional-reactive-programming-intro]

 

The ReactiveCocoa Project

There are many implementations of FRP in most of the popular languages.  I believe Java, and .NET were among the first to really get widespread adoption.  In the world of Cocoa programming (Swift/Objective-C) the framework I am most familiar with is ReactiveCocoa.  

A little history on this project.  

Version 2.x was to this point the most popular.  However, it was Obj-C.  It was stable and fantastic, but oh so many square brackets!!!  ReactiveCocoa relies heavily on chaining methods.  For every method chained, a new set of square brackets.  It wasn't uncommon to have a statement, beginning like

 

[[[[[[RACObserve(self, username)...

Yikes.  But you eventually got used to it.  You have to be comfortable with brackets in order to be a regular objective-C programmer.

With the advent of Swift, a new version of ReactiveCocoa made it to release after a significant overhaul.  Not just porting code, but taking a step back and leveraging the strengths of Swift.  And best of all, no more square brackets!  Statements looked a bit cleaner.  Chaining was accomplished with a "propriatiary" |> operator.  Kinda Neat.  Problem is that when v3.0 finally had an official release. Swift 2.0 was in full swing, and an update was needed.

 

And this is where we find ourselves now.  The |> has been replaced with a more appropriate period.  And new Swift syntax is being leveraged.  As of this blog post ReactiveCocoa 4.0.1 is available having just become an official release.  This is where I'll pick up and start working through examples.  So for specific syntax and detailed usage I would recommend looking at the links referred to above.  The first thing I want to explore is the architecture of an FRP based app in ReactiveCocoa.

 

음 이전에는 [[[]]] 같이 괄호로 처리됐는데, |> 체이닝이 도입되었다 함.

 

링크 글도 이어서 본다.

 


[https://www.rapiddg.com/article/reactivecocoa-core-data-app-using-singleton-pattern]

 

Disclaimer: The way I describe things below is simply one way to do things.  I am not saying this is the best way.  It is simply the way that I, at this particular point in time, am putting together iOS applications using ReactiveCocoa and Core Data.

My approach is a little bit Singleton based and a little bit MVVM pattern based.  The size and complexity of a project determines how much I use one over the other.  The main principles I like in these patterns are 

여러 방법이 있겠지만, 내가 사용하는 접근법은 약간의 싱글톤에 기반한 MVVM 패턴 기반이다. 

 

  • Having one Data Management Class that all views can reliable goto for the state of the app. (uh oh, I said state, FRP is about removing state, which is a great principle, but I've not been able to completely eliminate state, at least not practically)

모든 뷰들이 앱의 스테이트를 향해 신뢰성 있게 한개의 데이터 관리 클래스를 갖는다. (???뭔소리지, 하~... 그리고 저자는, frp가 스테이트를 제거한다 했지만, 완전히 스테이트를 지우지는 못했다고 한다.)

 

  • Removing business logic from View Controllers.  The MVVM pattern suggests that we create a view model, and simply bind the values of a view controller to it's view model, leaving just the interactive stuff for the view controller to worry about.

뷰컨으로 부터 비즈니스 로직을 제거한다. MVVM 패턴은 우리가 뷰모델을 만들것을 제안한다. 그리고 뷰컨의 값들을 자신의 뷰모델로 연결하기 바란다, 뷰컨이 걱정할 인터엑티브한 부분은 전부 남겨둔다??

 

이 두 부분을 아직 정확히 이해 못했다.

 

 

Most Core Data based apps will have some requirement of pulling data from a remote service of some kind.  This means the app will get the data is uses from one of two different locations. Core Data, or the Web Service.  For testability, it's nice for the app to not care too much about where the data is coming from.  So adding some abstraction is a great idea.  I like to have all Data for the app originate in a class called DataManager.  The the DataManager will decide where to pull the data from based on a number of conditions.  Since there are two places data can come from we will create two more classes that will sit behind the DataManager class and each handle one data source.  I like to call the class that handles Core Data fetching the PersistenceClient, and the one that pulls from the remote service, the ServiceClient.  The DataManager will be the ONLY one who talks to these two classes, and the rest of the app ONLY talks to the DataManager for it's data.  

 

대부분의 코어 데이터에 기반한 앱들은 원거리 서비스로 부터 데이터를 갖고 와야한다. 이것은 앱이 사용하는 데이터를 한개 또는 두개 이상의 위치에서 갖고 온다는 것이다. 코어 데이터, 웹 서비스들등에서. 테스트를 위해서, 앱이 데이터를 어디서 갖고오는지 신경쓰지 않는 것은 매우 좋다. 그래서 몇몇 추상화 아이디어를 추가하자. 나는 앱의 모든 데이터를 DataManger에서 갖고오도록 하고싶다. DataManager는 어디서 데이터를 가져올것인지 몇가지 조건들에 기반해 판단할 것이다. 데이터가 올수있는 장소가 두개 이상이므로 우리는 DataManger뒤에 위치할 클래스를 두개 더 많들것이다 그리고 각각이 한 데이터 소스를 관리할 것이다. 나는 코어 데이터 패칭을 관리하는 클래스를 PersistentClient라 부를것이다, 그리고 원격 서비스에서 갖고오는 것은, ServiceClient라 부를것이다. DataManager는 이 두개의 클래스에 말하는 단 한개의 클래스일것이다, 그리고 나머지 앱은 오직 DataManager에 데이터를 요청할것이다.

 

I have the arrows pointing up the chain in the diagram, though from a reactive standpoint they should be going the other way.  Because signals from the Clients and DataManager are sending data to the rest of our app.  We do have to make calls to get the producers that create these signals.  So while in theory, data is flowing "down", we need to subscribe to this data which is more upward.

 

나는 도표에서 체인을 따라가는 화살표들을 갖는다, 리액티브 관점에서 각각은 다른 길로 가야한다. 왜냐하면 클라이언트에서의 신호들과 데이터매니저에서의 신호들은 우리 앱의 나머지로 데이터를 전송하고 있기 때문이다. 우리는 이러한 신호들을 만드는 producer들을 갖기위해 호출해야한다. 그래서 이론적으로, 데이터는 아래로 흐른다, 우리는 위쪽 방향으로 이러한 데이터에 구독해야한다.

 

 

이후 계속...

 

 

Example Scenario

Say our app is concerned with knowing the network status at any given point.  The DataManager can have a signal that sends values to it's observers anytime this status changes.  So anywhere in the app, we can subscribe to this signal and make the appropriate changes to the UI, etc.  I like to leverage the "library" Reachability from Ashley Mills.  Our method in the DataManager may look something like this.

First create a signal (not a SignalProducer) on the DataManager that we will send values on when things change.