[Swift] Alamofire vs Moya & URLSession์— ๋Œ€ํ•˜์—ฌ

2023. 1. 27. 17:07ใ†Programming/Swift

 

 

 

URLSession

The URLSession class and related classes provide an API for downloading data from and uploading data to endpoints indicated by URLs.
Your app can also use this API to perform background downloads when your app isn’t running or, in iOS, while your app is suspended. You can use the related URLSessionDelegate and URLSessionTaskDelegate to support authentication and receive events like redirection and task completion.

The URLSession API involves many different classes that work together in a fairly complex way which may not be obvious if you read the reference documentation by itself. Before using the API, read the overview in the URL Loading System topic. The articles in the Essentials, Uploading, and Downloading sections offer examples of performing common tasks with URLSession.

  • URL Loading System: Interact with URLs and communicate with servers using standard Internet protocols.
  •  The URL Loading System provides access to resources identified by URLs, using standard protocols like https or custom protocols you create. Loading is performed asynchronously, so your app can remain responsive and handle incoming data or errors as they arrive.
  • You use a URLSession instance to create one or more URLSessionTask instances, which can fetch and return data to your app, download files, or upload data and files to remote locations. To configure a session, you use a URLSessionConfiguration object, which controls behavior like how to use caches and cookies, or whether to allow connections on a cellular network. 
Figure 1 : two sessions with these configurations can then create multiple tasks.
  • Each session is associated with a delegate to receive periodic updates (or errors). The default delegate calls a completion handler block that you provide; if you choose to provide your own custom delegate, this block is not called.
  • You can configure a session to run in the background, so that while the app is suspended, the system can download data on its behalf and wake up the app to deliver the results.
  • You can use one session repeatedly to create tasks.
    For example, a web browser might have separate sessions for regular and private browsing use, where the private session doesn’t cache its data. 
    Figure 1 shows how two sessions with these configurations can then create multiple tasks.

 

  • Essentials Configure and create sessions(์„ธ์…˜์„ ๊ตฌ์„ฑํ•˜๊ณ  ์ƒ์„ฑ), then use them to create tasks that interact with URLs.
  • Fetching Website Data into Memory : Receive data directly into memory by creating a data task from a URL session.
  • Analyzing HTTP Traffic with Instruments : Measure HTTP-based network performance and usage of your apps.
  • class URLSession : An object that coordinates a group of related, network data transfer tasks.
  • class URLSessionTask : A task, like downloading a specific resource, performed in a URL session.

 

  • Requests and Responses (๋‚ด๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์Œ)
  • struct URLRequest : A URL load request that is independent of protocol or URL scheme. (๋‚ด๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค)
  • class URLResponse : The metadata (๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ, ์ฆ‰ ์ •๋ณด) associated with the response to a URL load request, independent of protocol and URL scheme. (independent๋Š” ์™œ ์ž๊พธ ๋‚˜์˜จ ๊ฑธ๊นŒ?)
  • class HTTPURLResponse : The metadata associated with the response to an HTTP protocol URL load request.

 

 

 

 

๊ธฐ๋ณธ์ ์ธ URL Loading System์„ ์•Œ์•„๋ณด์•˜๋‹ค. ๋‹ค์‹œ URLSession์œผ๋กœ ๋Œ์•„์™€์„œ ... 

Your app creates one or more URLSession instances, each of which coordinates a group of related data-transfer tasks. For example, if you’re creating a web browser, your app might create one session per tab or window, or one session for interactive use and another for background downloads.
Within each session, your app adds a series of tasks, each of which represents a request for a specific URL (following HTTP redirects, if necessary).

 

Types of URL Sessions

The tasks within a given URL session share a common session configuration object, which defines connection behavior, like the maximum number of simultaneous connections to make to a single host, whether connections can use the cellular network, and so on.

URLSession has a singleton shared session (which doesn’t have a configuration object) for basic requests. It’s not as customizable as sessions you create, but it serves as a good starting point if you have very limited requirements. You access this session by calling the shared class method. (์„œ๋ฒ„, manager ๊ด€๋ จ ์ฝ”๋“œ์—์„œ ํ™œ์šฉํ•˜๋Š” ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด!) 
For other kinds of sessions, you create a URLSession with one of three kinds of configurations:

  • A default session behaves much like the shared session, but lets you configure it.
    You can also assign a delegate to the default session to obtain data incrementally. (์ ์ง„์ ์œผ๋กœ)
  • Ephemeral sessions are similar to shared sessions, but don’t write caches, cookies, or credentials to disk. (์ž„์‹œ)
  • Background sessions let you perform uploads and downloads of content in the background while your app isn’t running.

See Creating a Session Configuration Object in the URLSessionConfiguration class for details on creating each type of configuration. (์ด์ œ ์ข€ ์ดํ•ด๊ฐ€ ๋˜๋„ค)

 

Types of URL Session Tasks

Within a session, you create tasks that optionally upload data to a server and then retrieve data from the server either as a file on disk or as one or more NSData objects in memory.
The URLSession API provides four types of tasks:

  • Data tasks send and receive data usingNSDataobjects.
    Data tasks are intended for short, often interactive requests to a server.
  • Upload tasks are similar to data tasks, but they also send data (often in the form of a file), and support background uploads while the app isn’t running.
  • Download tasks retrieve data in the form of a file, and support background downloads and uploads while the app isn’t running.
  • WebSocket tasks exchange messages over TCP and TLS, using the WebSocket protocol defined in RFC 6455. ์›น์†Œ์ผ“์ด ๋ญ์ง€? ์„œ๋ฒ„์™€ ๋ธŒ๋ผ์šฐ์ € ์‚ฌ์ด์— ์–‘๋ฐฉํ–ฅ ์†Œํ†ต์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค. ํ•˜๋‚˜์˜ TCP ์ ‘์†์— ์ „์ด์ค‘ ํ†ต์‹  ์ฑ„๋„์„ ์ œ๊ณตํ•˜๋Š” ์ปดํ“จํ„ฐ ํ†ต์‹  ํ”„๋กœํ† ์ฝœ, ์›น์†Œ์ผ“ ํ”„๋กœํ† ์ฝœ์€ 2011๋…„ IETF์— ์˜ํ•ด RFC 6455๋กœ ํ‘œ์ค€ํ™”๋˜์—ˆ์œผ๋ฉฐ, ์›น IDL์˜ ์›น์†Œ์ผ“ API๋Š” W3C์— ์˜ํ•ด ํ‘œ์ค€ํ™”๋˜๊ณ  ์žˆ๋‹ค. ์›น์†Œ์ผ“์€ HTTP์™€ ๊ตฌ๋ณ„๋œ๋‹ค. CS ์ฑ… ์ฝ๋‹ค๊ฐ€, ๋„คํŠธ์›Œํฌ ํŒŒํŠธ์—์„œ ๋ดค๋˜ ๊ธฐ์–ต์ด ๋‚œ๋‹ค.

 

Using a Session Delegate

Tasks in a session also share a common delegate object. You implement this delegate to provide and obtain information when various events occur, including when:

  • Authentication fails. (์ธ์ฆ ์‹คํŒจ)
  • Data arrives from the server. (์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์™”์„ ๋•Œ!)
  • Data becomes available for caching. (์บ์‹ฑ -> ์ด์ „์— ๊ฒ€์ƒ‰ํ•˜๊ฑฐ๋‚˜ ๊ณ„์‚ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค)

If you don’t need the features provided by a delegate, you can use this API without providing one by passing nil when you create a session. 

 

 

Important

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session.
If you don’t invalidate the session, your app leaks memory until the app terminates.

Each task you create with the session calls back to the session’s delegate, using the methods defined in URLSessionTaskDelegate.
You can also intercept these callbacks before they reach the session delegate by populating a separate delegate that’s specific to the task.

 

Asynchronicity and URL Sessions (๋น„๋™๊ธฐ์„ฑ)

Like most networking APIs, the URLSession API is highly asynchronous. It returns data to your app in one of three ways, depending on the methods you call:

  • If you’re using Swift, you can use the methods marked with the asynckeyword to perform common tasks.
    For example, data(from:delegate:) fetches data, while download(from:delegate:)downloads files.
    Your call point uses the await keyword to suspend(์œ ์˜ˆ == ์ง€์—ฐ) running until the transfer completes.
    You can also use the bytes(from:delegate:) method to receive data as an AsyncSequence. With this approach, you use the for-await-in syntax to iterate over the data as your app receives it.
    The URL type also offers covenience methods to fetch bytes or lines from the shared URL session.
  • In Swift or Objective-C, you can provide a completion handler block, which runs when the transfer completes.
  • In Swift or Objective-C, you can receive callbacks to a delegate method as the transfer progresses and immediately after it completes.

In addition to delivering this information to delegates, the URLSession provides status and progress properties. Query these properties if you need to make programmatic decisions based on the current state of the task (with the caveat(๊ฒฝ๊ณ ) that its state can change at any time).

 

Protocol Support

The URLSession class natively supports the data, file, ftp, http, and https URL schemes, with transparent support for proxy servers and SOCKS gateways, as configured in the user’s system preferences.

URLSession supports the HTTP/1.1, HTTP/2, and HTTP/3 protocols.
HTTP/2 support, as described by RFC 7540, requires a server that supports Application-Layer Protocol Negotiation (ALPN).

You can also add support for your own custom networking protocols and URL schemes (for your app’s private use) by subclassing URLProtocol.

 

App Transport Security (ATS)

iOS 9.0 and macOS 10.11 and later use App Transport Security (ATS) for all HTTP connections made with URLSession. ATS requires that HTTP connections use HTTPS (RFC 2818). For more information, see NSAppTransportSecurity.

 

Foundation Copying Behavior

Session and task objects conform to the NSCopying protocol as follows:

  • When your app copies a session or task object, you get the same object back.
  • When your app copies a configuration object, you get a new copy you can independently modify.
  • ์ด๊ฒƒ๋„ copy by reference vs value ๊ฐœ๋… ๊ฐ™๋‹ค. ๊ตฌ์„ฑ์€ ๋…๋ฆฝ(๊ฐ’๋งŒ, ๋ณต์‚ฌ๋ณธ), ์„ธ์…˜๊ณผ ํƒœ์Šคํฌ๋Š” ๋™์ผ ๊ฐ์ฒด ๋ฐ˜ํ™˜

 

Thread Safety (์Šค๋ ˆ๋“œ ์•ˆ์ „)

The URL session API is thread-safe.
You can freely create sessions and tasks in any thread context.
When your delegate methods call the provided completion handlers, the work is automatically scheduled on the correct delegate queue.

  • ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋–ค ํ•จ์ˆ˜๋‚˜ ๋ณ€์ˆ˜, ํ˜น์€ ๊ฐ์ฒด๊ฐ€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ๋™์‹œ์— ์ ‘๊ทผ์ด ์ด๋ฃจ์–ด์ ธ๋„ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†์Œ์„ ์˜๋ฏธ
  • ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๊ฐ€ ํ•œ ์Šค๋ ˆ๋“œ์—์„œ ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰์ค‘์ผ ๋•Œ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๋™์‹œ์— ์‹คํ–‰๋˜๋”๋ผ๋„, ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ์˜ ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๊ฐ€ ์˜ฌ๋ฐ”๋กœ ๋‚˜์˜ค๋Š” ๊ฒƒ์œผ๋กœ ์ •์˜

 

  • ์Šค๋ ˆ๋“œ์— ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•
  • Re-entrancy 
    ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ํ•œ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰์ค‘์ผ ๋•Œ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋”๋ผ๋„ ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ๊ฐ์—๊ฒŒ ์˜ฌ๋ฐ”๋กœ ์ฃผ์–ด์ ธ์•ผ ํ•œ๋‹ค. ์Šค๋ ˆ๋“œ๋ผ๋ฆฌ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์งœ๋ผ๋Š” ๊ฒƒ
  • Thread-local-storage
    ๊ณต์œ  ์ž์›์˜ ์‚ฌ์šฉ์„ ์ตœ๋Œ€ํ•œ ์ค„์—ฌ ๊ฐ๊ฐ์˜ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ €์žฅ์†Œ๋“ค์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋™์‹œ ์ ‘๊ทผ์„ ๋ง‰๋Š”๋‹ค. ์ „์—ญ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ์ž์ œํ•˜๋ผ๋Š” ๋œป
  • Mutual exclusion
    ๊ณต์œ  ์ž์›(์ „์—ญ ๋ณ€์ˆ˜ ๋“ฑ)์„ ๊ผญ ์‚ฌ์šฉํ•ด์•ผ ๋  ๊ฒฝ์šฐ์—๋Š”, ํ•ด๋‹น ์ž์›์˜ ์ ‘๊ทผ์„ ์„ธ๋งˆํฌ์–ด ๋“ฑ์˜ ๋ฝ์œผ๋กœ ํ†ต์ œ
    ์˜ˆ๋ฅผ ๋“ค๋ฉด, Python์—์„œ์˜ threading.lock์ด ์žˆ๋‹ค. threading.lock์„ acquireํ•˜๋ฉด ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋งŒ ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , lock์„ releaseํ•ด์•ผ๋งŒ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค
  • Atomic operations
    ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ๋•Œ ์›์ž ์—ฐ์‚ฐ์„ ์ด์šฉํ•˜๊ฑฐ๋‚˜ ์›์ž์ ์œผ๋กœ ์ •์˜๋œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•จ -> ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๊ตฌํ˜„
    ex) a += b์˜ ๊ฒฝ์šฐ, ๋จผ์ € +์—ฐ์‚ฐ์„ ํ•œ ๋’ค์— =์—ฐ์‚ฐ์„ ํ•˜๋ฏ€๋กœ, ์›์ž์ ์ด๋ผ๊ณ  ๋ณด๊ธฐ ์–ด๋ ต๋‹ค.

 

  • ๋„ค ๊ฐ€์ง€์˜ ๋ฐฉ๋ฒ•๋“ค ์ค‘์— thread-safeํ•œ ์ƒํ™ฉ์ด ๋ช…๋ฐฑํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•œ๋‹ค๋ฉด, ๋ณดํ†ต์€ Mutual exclusion(๋™๊ธฐํ™” ๊ฐ์ฒด)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ด๋‹ค. ์ด๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์‰ฝ๊ธฐ ๋•Œ๋ฌธ 
  • ์‹ค์ƒํ™œ์—์„œ ์ด mutual exclusion์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ๋Š”, GIL์ด ์žˆ๋‹ค. GIL์ด๋ž€ Global Interpreter Lock์˜ ์ค„์ž„๋ง๋กœ, Python ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ํ•˜๋‚˜์˜ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” Lock์„ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—๋งŒ ๋ชจ๋“  ์ž์›์„ ํ—ˆ๋ฝํ•˜๊ณ  ๊ทธ ์ดํ›„์—๋Š” ๋ฝ์„ ๊ฑธ์–ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.
  • Python์—์„œ GIL์ด ํ•„์š”ํ•œ ์ด์œ ๊ฐ€, CPython์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์ƒํƒœ๊ฐ€ thread-safeํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ
    ์ฆ‰, ์ด๋Ÿฌํ•œ ์Šค๋ ˆ๋“œ ์•ˆ์ „์˜ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด GIL์ด๋ผ๋Š” ๊ฒƒ

 

 

 

apple ๊ณต์‹๋ฌธ์„œ์™€ ๊ธฐํƒ€ ์ž๋ฃŒ๋“ค์„ ํ†ตํ•˜์—ฌ URLSession์„ ํŒŒ์•…ํ•ด๋ณด์•˜๋‹ค. ๋‹ค์Œ์œผ๋กœ Alamofire & Moya์— ๋Œ€ํ•˜์—ฌ ์•Œ์•„๋ณด์ž.

Alamofire

 

  • Moya๋Š” Alamofire ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•œ์ธต ๋” Wrappingํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธ๋ฆฌํ•˜๋„๋ก ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • Wrapping์€ ์‚ฌ์šฉ์˜ ํŽธ์˜์„ฑ์ด๋ผ๋Š” ์žฅ์ ๋„ ์ œ๊ณตํ•˜์ง€๋งŒ, URLSession์— ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ๋‹ค
  • ์ตœ๊ทผ ์ด๋ฅผ ๋Š๋ผ๊ณ  ํ•œ ๊ณ„์ธต ๋‚ฎ์€ Alamofire ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ• ์ง€, ์•„๋‹ˆ๋ฉด ์ˆœ์ˆ˜ URLSession์„ Moduleํ™”ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ง€ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€, ๊ทธ๋ž˜๋„ ์กฐ๊ธˆ์€ Moduleํ™”๊ฐ€ ๋˜์–ด์žˆ๋Š” Alamofire ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋Œ๋ฐœ ์ƒํ™ฉ ๋Œ€์ฒ˜์— ์ข‹์„ ๊ฒƒ ๊ฐ™์•„ Alamofire๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •
  • ๊ฐœ์ธ์ ์œผ๋กœ Moya์˜ ์‚ฌ์šฉ์— ์ต์ˆ™ํ•ด์ ธ ์žˆ๊ณ , ์ฒด๊ณ„์ ์œผ๋กœ ๊ธฐ๋Šฅ์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํŠน์„ฑ์ƒ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์œ ์ง€๋ณด์ˆ˜์— ์žฅ์ ์ด ์žˆ๋‹ค๋Š” ์ ์„ ๋Š๊ผˆ๊ธฐ์— Alamofire๋ฅผ Moya์ฒ˜๋Ÿผ ๋งŒ๋“ค์–ด๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

 

  • Foundation Framework
  • ํŒŒ์šด๋ฐ์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ๋„คํŠธ์›Œํฌ ์ฒ˜๋ฆฌ, ํŒŒ์ผ ์ฒ˜๋ฆฌ์™€ ๊ฐ™์€ ํ•„์ˆ˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณต
  • ํŒŒ์šด๋ฐ์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค๋Š” ์ด๋ฆ„ ์•ž์— NS๋ฅผ ๋ถ™์ธ๋‹ค.
    ex) NSData, NSArray, NSURL์€ ํŒŒ์šด๋ฐ์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค
  • ํŒŒ์šด๋ฐ์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์ƒ๋‹จ์— import ๋ฌธ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
    • import Foundation

 

  • Alamofire
  • ํŒŒ์šด๋ฐ์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” API๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด URLRequest ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ–ˆ์ง€๋งŒ,
    Alamoifire๋Š” ๋”์šฑ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ.
  • Alamofire ๋Š” ๋น„๋™๊ธฐ ๊ธฐ๋ฐ˜์œผ๋กœ ๋„คํŠธ์›Œํฌ ์‘๋‹ต์„ ์ฒ˜๋ฆฌ
    ์‘๋‹ต ๋ฉ”์‹œ์ง€๋ฅผ reponse ๋ฉ”์†Œ๋“œ์˜ ๊ฒฐ๊ณผ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์—†๋‹ค.
    ์„œ๋ฒ„์—์„œ ์‘๋‹ต์ด ๋„์ฐฉํ–ˆ์„๋•Œ ์‹คํ–‰๋  ๋กœ์ง์„ ํด๋กœ์ € ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•ด, reponse ๋ฉ”์†Œ๋“œ์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•จ (์ฝœ๋ฐฑ ํ•จ์ˆ˜)
  • Alamofire ๋Š” ์„œ๋ฒ„์—์„œ ์‘๋‹ต์ด ๋„์ฐฉํ•˜๋ฉด ์ด๋ฅผ ํด๋กœ์ €์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋‹ด์•„ ํ˜ธ์ถœํ•œ๋‹ค.

 

 

 

 

โœณ๏ธ ํŒŒ์šด๋ฐ์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•˜์—ฌ API ํ˜ธ์ถœํ•˜๊ธฐ

  • GET ๋ฐฉ์‹์œผ๋กœ ํ˜„์žฌ ์‹œ๊ฐ„ ํ™•์ธ API ํ˜ธ์ถœํ•˜๊ธฐ
  • POST ๋ฐฉ์‹์œผ๋กœ ์—์ฝ” API ํ˜ธ์ถœํ•˜๊ธฐ
  • JSON ๋ฐฉ์‹์œผ๋กœ ์—์ฝ” JSON API ํ˜ธ์ถœํ•˜๊ธฐ

 

 

 

1) GET ๋ฐฉ์‹์œผ๋กœ ํ˜„์žฌ ์‹œ๊ฐ„ ํ™•์ธ API ํ˜ธ์ถœํ•˜๊ธฐ

CurrentTime API ํ˜ธ์ถœ ํ˜•์‹

  • Description : ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ํ˜„์žฌ ์‹œ๊ฐ„์„ ๊ฐ€์ ธ์˜จ๋‹ค.
  • URL : 
  • Method : GET
  • Request : ์—†์Œ
  • Response : ๋‚ ์งœ ํ˜•ํƒœ์˜ ๋ฌธ์ž์—ด(ex. 2020-09-04 13:29:46)
    • ๊ฐ’์„ ์š”์ฒญํ•  ๋•Œ ์ „๋‹ฌ๊ฐ’(request, req)์—๋Š” ์•„๋ฌด ๊ฒƒ๋„ ํฌํ•จํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

 

 

2) POST ๋ฐฉ์‹์œผ๋กœ API ํ˜ธ์ถœํ•˜๊ธฐ

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ์š”์ฒญ์„ ๊ทธ๋Œ€๋กœ ์‘๋‹ตํ•˜๋Š” Echo API ํ˜ธ์ถœ

๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ฒ˜์Œ ์—ฐ๋™ํ•  ๋•Œ ์„œ๋ฒ„๊ฐ€ ์ž˜ ์‘๋‹ตํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์‚ฌ์šฉ

ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ๋‚ด์šฉ์„ JSON ํ˜•์‹์œผ๋กœ ๋Œ๋ ค์ฃผ๊ณ , ๊ฑฐ๊ธฐ์— ๋”ํ•ด timestamp ์™€ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋Š” result ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์‘๋‹ตํ•œ๋‹ค.

 

Echo API ์š”์ฒญ ํ˜•์‹

  • Description : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ์š”์ฒญ์„ ๊ทธ๋Œ€๋กœ JSON ํ˜•์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์‘๋‹ตํ•œ๋‹ค.
  • URL : 
  • Method : POST
  • Content Type : x-www-form-urlencoded
  • Request : ์‚ฌ์šฉ์ž ์ •์˜ ํ˜•์‹
  • Response : JSON ๊ฐ์ฒด. ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ ๋‚ด์šฉ ๊ทธ๋Œ€๋กœ / result: ์„ฑ๊ณต์‹œ SUCCESS, ์‹คํŒจ์‹œ FAIL / timestmp : ์‘๋‹ต ์‹œ๊ฐ„์„ YYYY-MM-dd HH:mm:ss ํ˜•ํƒœ๋กœ ํ‘œํ˜„
    • GET ๋ฐฉ์‹๊ณผ ๋‹ค๋ฅด๊ฒŒ Content Type ์ด ์žˆ๋‹ค. ์„œ๋ฒ„์— ๊ฐ’์„ ์ „์†กํ•  ๋•Œ URL ์ธ์ฝ”๋”ฉ๋œ ํผ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ.
      ๋ณดํ†ต ์›นํŽ˜์ด์ง€์˜ form ์—์„œ submit ๋ˆŒ๋ €์„๋•Œ ๊ฐ’์ด ์ „๋‹ฌ๋˜๋Š” ํ˜•์‹์ด x-www-form-urlencoded ์ด๋‹ค.

 

 

1. ์ „์†กํ•  ๊ฐ’ ์ค€๋น„
๊ฐ’์„ POST ๋ฐฉ์‹์œผ๋กœ ์ „์†กํ•˜๋ ค๋ฉด http ํ†ต์‹  ํ‘œ์ค€์— ์ •์˜๋œ ์•ฝ์†์— ๋”ฐ๋ผ, key1=value1&key2=value2&... ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ณด๋‚ด๋ฉด ๊ณต๋ฐฑ์ด๋‚˜ ๋ฌธ์žฅ๋ถ€ํ˜ธ, ํ•œ๊ธ€ ๊ฐ™์€ ๋ฌธ์ž๋Š” ์ „์†ก๊ณผ์ •์—์„œ ๋ณ€ํ˜•๋˜์–ด ๋ฒ„๋ฆด ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ Data ๊ฐ์ฒด๋กœ ๋ณ€๊ฒฝํ• ๋•Œ .utf8 ์ธ์ฝ”๋”ฉ์„ ์ ์šฉํ•ด์ค˜์•ผ ํ•œ๋‹ค.

 

2. URL ๊ฐ์ฒด ์ •์˜
API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณผ์ •์˜ ๋Œ€๋ถ€๋ถ„์€ URL ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.

 

3. URLRequest ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๊ณ  ์š”์ฒญ ๋‚ด์šฉ์„ ๋‹ด๋Š”๋‹ค.
์ƒ์„ฑ๋œ URL ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ URLRequest ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.
์ด ๊ฐ์ฒด๋Š” API๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ํ•„์š”ํ•œ ์š”์ฒญ ๋‚ด์šฉ์ด ๋ชจ๋‘ ํฌํ•จ๋˜๋ฉฐ, http ์š”์ฒญ ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 

4. http ๋ฉ”์‹œ์ง€์˜ ํ—ค๋”๋ฅผ ์„ค์ •ํ•œ๋‹ค.
ํ—ค๋”๋Š” ์‹ค์ œ ๋‚ด์šฉ์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉด์„œ ์ „์†กํ•˜๋Š” ์ฝ˜ํ…์ธ ์— ๋Œ€ํ•œ ํ˜•์‹์ด๋‚˜ ํŠน์„ฑ ๋“ฑ ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
(๋ฉ”ํƒ€๋ฐ์ดํ„ฐ - ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ! ์•ž์„œ ์–ธ๊ธ‰๋˜์—ˆ๋‹ค.)
request.addValue(: forHTTPHeaderField: )์™€ request.setValue(: forHTTPHeaderField: ) ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํ—ค๋”๋ฅผ ์ถ”๊ฐ€
์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ํ—ค๋”์˜ ์ˆ˜์—๋Š” ์ œํ•œ์ด ์—†์œผ๋ฏ€๋กœ, ํ•„์š”ํ•œ ๋งŒํผ ์œ„ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
addValue ๋Š” ํ—ค๋”์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๊ณ , setValue ๋Š” ๊ธฐ์กด๊ฐ’์„ replace ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.


Content-Length ๋ฅผ ์„ค์ •ํ•œ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
์„œ๋ฒ„์— ์ „์†ก๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฌธ์ž์—ด์ด ๋ฉ์–ด๋ฆฌ ๋‹จ์œ„๋กœ ๋Š์–ด์ ธ์„œ ์ „์†ก๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ŠคํŠธ๋ฆผ ํ˜•์‹์œผ๋กœ ๊ณ„์† ์ด์–ด์ ธ ์ „๋‹ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ฒ„๋Š” http ๋ฉ”์‹œ์ง€๋ฅผ ์–ด๋””๊นŒ์ง€ ๋Š์–ด์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. http ๋ฉ”์‹œ์ง€ ๊ธธ์ด๋ฅผ ํŒ๋ณ„ํ•˜๊ธฐ ์œ„ํ•œ ํ—ค๋”.
Content-Length ํ—ค๋”๊ฐ€ ์—†์–ด๋„ ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋ฒ„๋Š” http ๋ฉ”์‹œ์ง€์˜ ๋์„ ์ž˜ ํŒ๋ณ„ํ•˜์ง€๋งŒ, ๋ณธ๋ฌธ์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•˜๋‹ค.
Data ๊ฐ์ฒด ๊ฐ’์˜ ๊ธธ์ด๋Š” count ์†์„ฑ์„ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ํ—ค๋”์— ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ๋ฌธ์ž์—ด ํ˜•์‹์œผ๋กœ ๋ณ€๊ฒฝํ•ด์„œ ์ง‘์–ด๋„ฃ์–ด์•ผ ํ•œ๋‹ค.

 

5. URLSession ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์ „์†ก ๋ฐ ์‘๋‹ต๊ฐ’ ์ฒ˜๋ฆฌ
URLRequest ๊ฐ์ฒด๋ฅผ ์ „์†กํ•˜๋Š”๋ฐ๋Š” URLSession.shared.dataTask(with:) ๊ตฌ๋ฌธ์ด ์‚ฌ์šฉ๋œ๋‹ค. ์ธํ’‹์— URLRequest ๊ฐ์ฒด๋ฅผ ๋‹ด๊ณ , ๋’ค์— ์ด์–ด์งˆ ํŠธ๋ ˆ์ผ๋ง ํด๋กœ์ €์—๋Š” ์‘๋‹ต์ด ์˜ฌ๋•Œ ์ฒ˜๋ฆฌ๋  ๋กœ์ง์ด ๋“ค์–ด๊ฐ„๋‹ค.
์‘๋‹ต๊ฐ’์˜ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”์—†๋Š” ์š”์ฒญ์ด๋ผ๋ฉด ํŠธ๋ ˆ์ผ๋ง ํด๋กœ์ €๋ฅผ ์ƒ๋žตํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋žตํžˆ ์ ์„ ์ˆ˜ ์žˆ๋‹ค.

let task = URLSession.shared.dataTask(with: request)

http ํ†ต์‹ ์€ ๋น„๋™๊ธฐ๋กœ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์—, ์‘๋‹ต๊ฐ’์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•  ๋‚ด์šฉ์„ ํด๋กœ์ € ํ˜•ํƒœ๋กœ ๋ฏธ๋ฆฌ ์ž‘์„ฑํ•˜์—ฌ ์ธ์ž๊ฐ’์œผ๋กœ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
์‘๋‹ต ํด๋กœ์ €์—๋Š” ์‘๋‹ต ๋ฉ”์‹œ์ง€ ๋ณธ๋ฌธ(Data ํƒ€์ž…์˜ data), ์‘๋‹ต ์ฝ”๋“œ ๋ฐ ๋ฉ”ํƒ€์ •๋ณด๊ฐ€ ์ €์žฅ๋œ ์‘๋‹ต์ •๋ณด(URLResponse ํƒ€์ž…์˜ response), ์˜ค๋ฅ˜์ •๋ณด(Error ํƒ€์ž…์˜ error) ๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ค์–ด๊ฐ„๋‹ค.
์„œ๋ฒ„ ํ†ต์‹ ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด ์„ธ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— Error ํƒ€์ž…์˜ ๊ฐ’์ด ๋Œ€์ž…๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์‘๋‹ต ์‹œ ์„ธ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฒดํฌํ•˜๋ฉด ํ†ต์‹ ์ด ์ œ๋Œ€๋กœ ์ˆ˜ํ–‰๋˜์—ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
Swift ์—์„œ ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“  ๊ตฌ๋ฌธ์€ ์„œ๋ธŒ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๊ณ , UI ๊ด€๋ จ ๊ตฌ๋ฌธ์€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„๋™๊ธฐ๋กœ ์ˆ˜ํ–‰๋˜๋Š” URLSession ํ•ธ๋“ค๋ง์€ ์„œ๋ธŒ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„ ํ†ต์‹ ์œผ๋กœ ์–ป์€ ๊ฒฐ๊ณผ๋ฌผ์„ UI ์— ๋ฐ˜์˜์‹œ์ผœ์•ผ ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ธŒ ์Šค๋ ˆ๋“œ ๋Œ€์‹  ๋ฉ”์ธ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
์„œ๋ธŒ์Šค๋ ˆ๋“œ ๋Œ€์‹  ๋ฉ”์ธ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๋„๋ก DispatchQueue.main.async() ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•œ๋‹ค.
์„œ๋ฒ„ ํ†ต์‹ ์œผ๋กœ ๋ฐ›์•„์˜จ jsonObject๋ฅผ NSDictionary ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ๊ฐ๊ฐ ๊ฐ’์„ ์ถœ๋ ฅํ•ด์„œ ํ…์ŠคํŠธ์— ์ง‘์–ด๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

 

6. POST ์ „์†ก
1~5๊นŒ์ง€, http ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ๊ณผ ๊ด€๋ จ๋œ ๋กœ์ง์ด ์ „๋ถ€ ์ž‘์„ฑ ๋˜์—ˆ์œผ๋ฉด task.resume()์„ ํ˜ธ์ถœํ•ด์„œ ์„œ๋ฒ„์— ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.

URL ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , URLSession ์— URL ๊ฐ์ฒด๋ฅผ ๋‹ด์•„ ๋ณด๋‚ด๊ณ , ์‘๋‹ต์„ ํŒŒ์‹ฑํ•˜์—ฌ ์›ํ•˜๋Š”๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

 

 

3) JSON ๋ฐฉ์‹์œผ๋กœ API ํ˜ธ์ถœํ•˜๊ธฐ

์ด๋ฒˆ์—๋Š” Echo API ํ˜ธ์ถœํ• ๋•Œ์™€ ๋น„์Šทํ•˜์ง€๋งŒ, Request ๊ฐ€ JSON ํ˜•์‹์„ ๋”ฐ๋ฅด๋Š” ํ˜ธ์ถœ์„ ์‹œ๋„ํ•œ๋‹ค.

JSON ๋ฐฉ์‹์˜ API ํ˜ธ์ถœ์€ ์ƒ์šฉ ์„œ๋น„์Šค์—์„œ ๋งŽ์ด ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
์ „์†กํ•  ๊ฐ’์„ =์™€ &๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๋Œ€์‹  JSON ํ˜•์‹์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ณ , Content-Type ํ—ค๋”๋ฅผ application/json ์œผ๋กœ ๋ณ€๊ฒฝ

 

 

 

 

 

 

Moya

  • Moya์—๋Š” Alamofire ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.
  • Alamofire๊ฐ€ ์žˆ์ง€๋งŒ ๊ตณ์ด Moyaํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 
    • Alamofire๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, URL๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๋•Œ request์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•˜๋ฉฐ(Network Layer์ ‘๊ทผ),
      ํ…œํ”Œ๋ฆฟ์ด ๊ฐ–์ถ”์–ด ์ง€์ง€ ์•Š์•„์„œ ์žฌ์‚ฌ์šฉ์— ์œ ๋ฆฌํ•˜์ง€ ์•Š์€ ๊ตฌ์กฐ
    • Moya๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Moya์—์„œ Network layer๋ฅผ ํ…œํ”Œ๋ฆฟํ™” ํ•ด๋†“๊ณ , ์‚ฌ์šฉํ•˜๋Š” App์—์„œ๋Š” request, response๋งŒ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋จ
  • Moya - Reactive Extensions : RxSwift ์™€ ReactiveSwift ์— ๋Œ€ํ•œ extensions ๋ฅผ ์ œ๊ณต

 

 

 

Moya๋ฅผ ํ†ตํ•ด ์ •๋ฆฌ๋œ ๋„คํŠธ์›Œํ‚น ํ๋ฆ„์€ ์„ธ๊ฐ€์ง€ ๋‹จ์ ์„ ๊ทน๋ณต

  • Makes it hard to write new apps ("where do I begin?")
  • Makes it hard to maintain existing apps ("oh my god, this mess...")
  • Makes it hard to write unit tests ("how do I do this again?")

Moya์˜ ํ›Œ๋ฅญํ•œ ์„ธ๊ฐ€์ง€ ํŠน์ง•์€

  • Compile-time checking for correct API endpoint accesses.
  • Lets you define a clear usage of different endpoints with associated enum values.
  • Treats test stubs as first-class citizens so unit testing is super-easy.

 

Moya์™€ Alamofire์˜ ์ฐจ์ด

  • Moya๋Š” ์ง์ ‘์ ์ธ ๋„คํŠธ์›Œํ‚น์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Œ : ์ž์ฒด์  ๋„คํŠธ์›Œํ‚น์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Œ
  • Alamofire๋Š” ์ง์ ‘์ ์ธ ๋„คํŠธ์›Œํ‚น์„ ์ˆ˜ํ–‰ํ•จ
  • ์ฆ‰, Moya๋Š” Alamofire์˜ ๋„คํŠธ์›Œํ‚น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ , Alamofire์„ ์ถ”์ƒํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ

 

 

 

  • URLSession
    • iOS ์•ฑ์—์„œ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•ด Apple์ด ์ œ๊ณตํ•˜๋Š” ๋„คํŠธ์›Œํ‚น API
    • ๋กœ์šฐ ๋ ˆ๋ฒจ์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•
    • Alamofire ์˜ ๊ธฐ๋ฐ˜์ด ๋˜๋Š” API
    • ํŠน์ • URL์„ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œ, ์—…๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•œ API
  • Alamofire
    • ๋„คํŠธ์›Œํ‚น ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • URLSession ์— ๊ธฐ๋ฐ˜ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • ์ฝ”๋“œ์˜ ๊ฐ„์†Œํ™” ๋ฐ ๊ฐ€๋…์„ฑ ์ธก๋ฉด์—์„œ ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๊ฐœ์„ ๋˜์—ˆ๋‹ค
    • ์œ ์ง€๋ณด์ˆ˜์™€ ์œ ๋‹› ํ…Œ์ŠคํŠธ๊ฐ€ ํž˜๋“ค๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค
  • Moya
    • ๋„คํŠธ์›Œํ‚น ์˜คํ”ˆ์†Œ์Šค ํ”„๋ ˆ์ž„์›Œํฌ
    • ์ถ”์ƒํ™” ๋œ ์ •๋„ : URLSession < Alamofire < Moya
    • Network Layer๋ฅผ ํ…œํ”Œ๋ฆฟํ™” : ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ธ๋‹ค
    • ์—ด๊ฑฐํ˜• enum์„ ์‚ฌ์šฉํ•ด์„œ ์•ˆ์ „ํ•˜๊ณ  ์ •๋ˆ๋œ ๋ฐฉ์‹์˜ ์บก์Šํ™”

 

 

  • What I like about Moya is being able to have all the endpoints of a particular service in one enum and being able to configure everything there, with convenient switch statements.
  • Using only Alamofire is a good solution as well, but in this case you have to provide some of the functionalities on top of that.

 

 

 

 

 

 

 

์ถœ์ฒ˜

 

Moya and Alamofire – Gualtiero Frigerio

As I was playing with my GitHub project about networking I thought it would be interesting to try some different ways to implement the RESTClient protocol. In this article I’m going to show how I used Alamofire and then Moya (which itself uses Alamofire)

www.gfrigerio.com