vmmap(Virtual Memory Map)

vmmap이란 Xcode, macOS에서 사용하는 가상 메모리 매핑 도구입니다.

특정 프로세스의 메모리 사용량을 맥 가상 메모리로 매핑하여 메모리 사용량을 보여줍니다.

터미널에서 사용하며, 실 기기의 메모리가 아니라 맥 기반 메모리를 매핑하게 됩니다.

 

 

vmmap 사용방법

Xcode에서 빌드 후 특정 프로세스중에서 확인하기 위해 break point를 걸거나 Debug Memory Graph를 열면 좌측에 프로젝트명 PID 번호가 나타나게 됩니다.

터미널에서 해당 PID를 이용하여 vmmap을 실행할 수 있습니다.

$ vmmap PID

실행 결과

_DATA, _TEXT:  실행코드 및 전역변수

malloc: 힙 영역

malloc guard page: 힙 오버플로우를 방지용 영역

stack: 스택 영역

stack guard: 스택 오버플로우 방지용 영역

 

해당 영역에 대한 주소범위도 나타낼 수 있습니다.

 

 

Stack 영역

$ vmmap PID | grep Stack

 

 

Heap(malloc) 영역

$ vmmap PID | grep Malloc

 

메모리 누수 확인

$ leaks PID

 

 

그래서 이걸 어디에 써먹고 왜 사용할까

데이터 사용량을 알 수 있다 해도 실제 기기에서의 데이터 사용량이 아닌 가상 메모리의 사용량입니다.

메모리 누수 현황을 알고 싶어도 현재 Xcode에서 Profile과 Debug Memory Graph 기능을 제공합니다.

 

현업에서 어디에 사용할 수 있는지 피드백도 받아보고 이런 저런 기능을 사용한 결과,

vmmap은 사용 하지 않아도 된다. 라는 결론이 나왔습니다.

 

Profile과 Debug Memory Graph는 vmmap보다 더 직관적인 UI를 제공합니다. 

그래서 객체간의 참조 관계나 누수 현황들을 보고 분석하기에 더 좋습니다.

 

vmmap은 더 낮은 레벨의 분석이 요구될 때 사용됩니다.

빠르게 터미널을 통해 메모리 사용량을 확인할 수 있지만,

특정 프로세스 즉 중단된 시점의 PID를 통해 메모리 사용량을 알 수 있고 실시간으로 확인하는것은 profile이 더 적합합니다.

 

따라서, 메모리 최적화의 큰 파이를 차지하는 메모리 누수해결은 현재 Xcode에서 지원하는 Profile과 Debug Memory Graph을 통해 훨씬 직관적으로 분석할 수 있기 때문에 vmmap까지 사용하지 않아도 됩니다..

 

'iOS' 카테고리의 다른 글

UICollectionViewLayout과 UICollectionViewFlowLayout  (0) 2025.03.03
UIBeizerPath  (0) 2025.02.26
NotificationCenter  (0) 2025.02.20
iOS Combine  (0) 2025.02.19
URLSession 번역  (0) 2024.12.13

CollectionView는 TableView와 다르게 layout을 설정해주지 않으면 생성시 오류가 발생합니다.

CollectionView 생성자에서 인자로 받는 UICollectionViewLayout이 있습니다.

왠만한 레이아웃은 UICollectionViewLayout으로 할 수 있지 않을까? 싶었는데 CollectionView 생성 인자로 모두 들어갈 수 있다는 점에서 많이 헷갈렸습니다.

이번 기회에 정리해보고자 합니다.

 

 

UICollectionViewLayout

https://developer.apple.com/documentation/uikit/uicollectionviewlayout

 

UICollectionViewLayout | Apple Developer Documentation

An abstract base class for generating layout information for a collection view.

developer.apple.com

 

- 컬렉션 뷰의 레이아웃을 설정하기 위한 클래스 입니다.

- 셀의 위치, 추가적인 뷰와 컬렉션 뷰 안의 데코레이션 뷰를 결정하고 컬렉션뷰에 전달합니다.

- UICollectionViewLayout을 사용하기위해 서브클래싱을 진행해야합니다.

 

 

Subclassing Notes

레이아웃 객체는 컬렉션뷰 아이템의 위치, 크기, 시각적 상태등을 디자인에 맞춰서 정의합니다.

레이아웃의 뷰는 컬렉션 뷰의 datasource에 의해 생성됩니다.

 

- Cell 은 레이아웃에 의해 배치되는 주요 요소입니다. 각 셀은 컬렉션 안의 단일 데이터 아이템으로 나타냅니다. 사용자가 각 항목을 선택, 끌기 재정렬 할 수 있도록 interactive한 셀을 만들 수 있습니다. 컬렉션 뷰는 단일 셀 그룹을 가질 수 있고 해당 셀을 여러 섹션으로 나눌 수 있습니다. 레이아웃 객체는 컬렉션뷰의 컨텐츠영역의 셀을 정렬할 수 있습니다.

- Supplementary view 데이터를 표시하지만 사용자가 선택할 수 없습니다. Header View와 Footer View를 구성하기 위해 사용됩니다. Supplementary view는 선택적으로 사용할 수 있고, 레이아웃 객체에서 정의합니다.

- Decoration view 선택할 수 없고, 컬렉션 뷰와 데이터로 연동되지 않은 뱃지와 같은 장식품입니다. Decoration viewSupplementary view 와는 다른 유형입니다. Supplementary view 와 마찬가지로 선택적으로 사용할 수 있고, 사용과 배치는 레이아웃 객체에서 정의합니다.

 

Collection View 는 위와 같은 레이아웃 정보를 제공하는 레이아웃 객체를 호출합니다. 스크린에 표시되는 모든 셀과 뷰는 레이아웃 객체를 사용하여 배치됩니다. 마찬가지로 항목이 추가되거나 삭제될 때 해당 항목에 대한 추가적인 레이아웃 단계가 발생합니다. 그러나 컬렉션 뷰는 레이아웃을 항상 스크린에 표시되는 객체로 제한합니다.

 

Methods

 

'iOS' 카테고리의 다른 글

메모리 사용량 확인을 위한 vmmap  (1) 2025.03.18
UIBeizerPath  (0) 2025.02.26
NotificationCenter  (0) 2025.02.20
iOS Combine  (0) 2025.02.19
URLSession 번역  (0) 2024.12.13

UIBeizerPath

A path that consists of straight and curved line segments that you can render in your custom views.
공식문서에 따르면, 사용자의 커스텀 뷰에서 렌더링할 수 있는 직선 곡선 세그먼트로 구성된 경로라고 합니다.

해당 객체는 UIKit의 Drawing에 속해있는 클래스입니다.

한마디로 사용자가 원하는 모양을 그려낼 수 있도록 도와주는 객체라고 생각하시면 됩니다.

 

init

UIBeizerPath를 생성하는데 기본으로 주어지는 모양들이 존재합니다.

// 기본 생성
public init()
// 직사각형 모양 CGRect를 인자로 받는다. CGRect(x: ,y: , width: , height: ,) x y 는 그리기의 시작지점, width height는 크기
public convenience init(rect: CGRect)

// 타원형 모양 CGRect를 인자로 받는다. CGRect(x: ,y: , width: , height: ,) x y 는 그리기의 시작지점, width height는 크기
public convenience init(ovalIn rect: CGRect)

// 둥근 사각형 모양 만든다. CGRect(x: ,y: , width: , height: ,) x y 는 그리기의 시작지점, width height는 크기 , cornerRadius 는 꼭지점의 둥근정도를 CGFloat 값으로 전달
public convenience init(roundedRect rect: CGRect, cornerRadius: CGFloat)

// 부분적으로 둥근 사각형 모양을 만든다. CGRect(x: ,y: , width: , height: ,) x y 는 그리기의 시작지점, width height는 크기
// UIRectCorner은 어느 꼭지점을 둥글게 만들지 결정
// cornerRadii 는 둥근 정도를 CGSize 값으로 받는다.
public convenience init(roundedRect rect: CGRect, byRoundingCorners corners: UIRectCorner, cornerRadii: CGSize)

// 원 모양으로 그린다.
// center: CGPoint(x:, y:) 원의 중간위치
// radius: 반지름
// startAngle: 그리기 시작 각도
// endAngle: 그리기 종료 각도
// clockwise: 시계방향으로 그릴지 Bool값으로 전달
public convenience init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)

// Core Graphics를 인자로 받아 경로 생성한다.
public convenience init(cgPath CGPath: CGPath)

 

이렇게 원, 직사각형, 타원형, 둥근 사각형 기타 등등 많은 표준된 모양을 지원해주지만, 사용자가 직접 그릴 수도 있습니다.

 

 

직접 그리기 

위와 같은 모양을 그리기 위해서 또는 선을 긋기 위해선 시작지점이 필요합니다.

// 생성
let path = UIBezierPath()

// 시작지점 지정
// CGPoint(x: ,y: )
path.move(to: CGPoint)

// 직선 생성
// CGPint(x: ,y: ) 시작지점에서 x,y 지점과 잇는 선 생성
path.addLine(to: CGPoint)

// 3차원 곡선 생성
path.addCurve(to: CGPoint, controlPoint1: CGPoint, controlPoint2: CGPoint)

// 가장 최근에 그어진 선의 끝 지점과 시작지점과 잇기
path.close()

// 현재까지 추가된 선을 모두 그리기
path.stroke()

// 현재까지 그려진 선이 둘러싼 영역을 채우기
path.fill()

 

'iOS' 카테고리의 다른 글

메모리 사용량 확인을 위한 vmmap  (1) 2025.03.18
UICollectionViewLayout과 UICollectionViewFlowLayout  (0) 2025.03.03
NotificationCenter  (0) 2025.02.20
iOS Combine  (0) 2025.02.19
URLSession 번역  (0) 2024.12.13

NotificationCenter

직역하면 알림센터로, Observer에게 Notification 객체를 전달하는 싱글톤 객체입니다.

델리게이트 패턴은 일대일 송수신에 장점이 있지만, 이 객체는 일대다, 다대다 통신의 장점을 갖고 있습니다.

 

Notification

    /// A tag identifying the notification.
    public var name: Notification.Name

    /// An object that the poster wishes to send to observers.
    ///
    /// Typically this is the object that posted the notification.
    public var object: Any?

    /// Storage for values or objects related to this notification.
    public var userInfo: [AnyHashable : Any]?

Notification에는 name, object, userInfo가 담겨져 있습니다.

name: 전달하고자 하는 Notification 식별 이름

object: 전달하는 데이터(객체)

userInfo: Notification과 관련된 데이터

 

Post(발송하기)

NotificationCenter.default.post(name: NSNotification.Name, object: Any?, userInfo: [AnyHashable : Any]?)

이벤트 발생 지점에서 NotificationCenter의 post를 통해 Notification을 전송합니다.

전송할때 식별되는 이름은 Notification.Name 입니다.

 

 

전달받기(Observer 등록)

NotificationCenter.default.addObserver(forName: NSNotification.Name?, object: Any?, queue: OperationQueue?, using: (Notification) -> Void)

알림을 받을 지점에서 Observer를 등록합니다.

알림받고 using: 클로저를 통해 바로 실행시키거나 알림을 받으면 메서드가 실행되도록 설정할 수 있습니다.

NotificationCenter.default.addObserver(Any, selector: Selector, name: NSNotification.Name, object: Any?)

 

'iOS' 카테고리의 다른 글

UICollectionViewLayout과 UICollectionViewFlowLayout  (0) 2025.03.03
UIBeizerPath  (0) 2025.02.26
iOS Combine  (0) 2025.02.19
URLSession 번역  (0) 2024.12.13
Fetching website data into memory  (0) 2024.12.10

Combine

Combine은 비동기 및 이벤트 처리 코드를 작성하는데 사용되는 프레임워크 입니다.

이전에 반응형 프로그래밍으로 RxSwift를 사용해 본 적이 있는데, 애플에서 개발한 Combine도 있다고 하여 개념을 정리해보고자 합니다

 

 

Publisher: 값을 생성하고 전달하는 객체입니다.

public protocol Publisher {
    associatedtype Output
    associatedtype Failure: Error

    func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
}

 

Subscriber: Publisher로부터 데이터를 수신하고 처리하는 객체입니다.

public protocol Subscriber: CustomCombineIdentifierConvertible {
    associatedtype Input
    associatedtype Failure: Error

    func receive(subscription: Subscription)
    func receive(_ input: Self.Input) -> Subscribers.Demand
    func receive(completion: Subscribers.Completion<Self.Failure>)
}

Operators: Publisher로부터 전달받은 값을 변환하거나 조작하는 객체입니다.

 

Combine의 흐름은 Publisher -> Operator -> Subscriber 순으로 진행됩니다.

 

 

'iOS' 카테고리의 다른 글

UIBeizerPath  (0) 2025.02.26
NotificationCenter  (0) 2025.02.20
URLSession 번역  (0) 2024.12.13
Fetching website data into memory  (0) 2024.12.10
URL Loading System 번역  (2) 2024.12.10

https://developer.apple.com/documentation/foundation/urlsession

 

URLSession | Apple Developer Documentation

An object that coordinates a group of related, network data transfer tasks.

developer.apple.com

 

 

URLSession

네트워크 데이터 통신 작업과 관련된 그룹을 조정하는 객체

 

해당 클래스는 URL로 표시된 엔드포인트에서 데이터를 다운로드하거나 업로드 하기 위한 API를 제공한다.

또한 앱이 실행되지 않거나 일시정지된 시점에서도 백그라운드에서 다운로드할 수 있는 기능을 제공

URLSessionDelegate와 URLSessionTaskDelegate를 사용하여 인증, 리디렉션과 같은 이벤트도 처리 가능

URL Loading System을 읽어보면 좋다.

 

앱은 하나 이상의 URLSession 인스턴스를 생성할 수 있고, 각 인스턴스는 데이터 전송 작업과 관련된 일을 수행할 수 있다.

예시로 앱이 탭이나 여러 창이 띄워져도 하나당 하나의 세션을 생성할 수 있고, 각자 독립적으로 네트워킹 작업을 수행할 수 있습니다.

각 세션과 함께 앱은 일련의 작업을 추가하고, 작업들은 특정 URL에 대한 요청을 나타냅니다.

 

 

URL session 형식

특정 URL session 내의 작업은 공통된 configuration 객체를 공유합니다.

Configuration 객체에는 단일 호스트에 대한 최대 동시 연결 수, 셀룰러 네트워크 사용 가능 여부 등의 동작을 정의합니다.

URLSession은 기본적으로 싱글톤인 shared 세션을 갖고 있습니다.

shared는 configuration 객체를 갖고 있지 않습니다.

싱글톤 shared는 커스터마이징할 수 없지만, 제한적이고 간단한 네트워크 요구사항을 갖는경우 사용하기 적합합니다.

shared는 shared 클래스 메서드를 호출하여 접근합니다.

 

다른 종류의 세션의 경우 세가지 구성중 하나로 URLSession을 생성할 수 있습니다.

  • 기본 세션은 shared 세션처럼 동작하지만 configuration을 통해 세션을 구성해야합니다. 기본 세션에 델리게이트를 할당하여 점진적으로 데이터를 얻을 수 있습니다.
  • 임시 세션은 shared 세션과 비슷합니다. 그러나 캐시나 쿠키 그리고 자격 증명을 디스크에 쓰지 않습니다.
  • 백그라운드 세션은 앱이 실행하지 않는 동안 백그라운드에서 컨텐츠의 다운로드 및 업로드를 수행하도록 합니다.

 

각 configuration 형식 생성에 대한 자세한 내용은 URLSessionConfiguration 클래스를 참조하세요.

 

 

URLSession 작업 형식

세션 내에서 선택적으로 데이터를 서버에 업로드한 다음 디스크의 파일 또는 메모리의 하나 이상의 NSData 객체로 서버에서 데이터를 검색하는 작업을 생성합니다.

 

URLSession API는 4가지 작업 유형을 제공함

  • 데이터 작업은 NSData 객체를 사용하여 수신 및 발신합니다. 데이터 작업은 짧은 시간동안 수행되고 요청들은 보통 쌍방향입니다.
  • 업로드 작업은 데이터 작업과 비슷하지만 파일형식의 데이터도 보낼 수 있습니다.(종종 파일 형태로) 그리고 앱이 실행되지 않아도 백그라운드 업로드를 지원합니다.
  • 다운로드 작업은 파일 형식으로 데이터를 검색하고 앱이 실행되지 않는 동안 백그라운드 다운로드 및 업로드를 지원합니다.
  • WebSocket 작업은 RFC 6455에 정의된 WebSocket 프로토콜을 사용하여 TCP 및 TLS를 통해 메세지를 교환합니다.

 

 

Session Delegate 사용하기

세션안의 작업들은 공통의 Delegate 객체를 공유합니다.

다양한 이벤트가 발생했을 때 정보를 얻거나 제공하기 위해 델리게이트를 지정해주어야 합니다.(아래와같은 이벤트)

  • 인증 실패
  • 서버로부터 데이터 도착
  • 캐싱이 가능해진 데이터

위와 같은 이벤트가 필요하지 않다면, session을 생성할 때 nil을 전달하여 API를 사용할 수 있습니다.

 

중요

세션 객체는 세션이 명시적으로 메모리해제 되거나 앱이 종료되기 전까지 델리게이트와 강한 참조를 유지합니다. 메모리 해제하지 않는다면 앱이 종료될때 까지 메모리 누수가 발생합니다.

 

세션으로 생성한 작업은 URLSessionTaskDelegate에 정의된 메서드를 사용하여 세션의 델리게이트를 다시 호출합니다.

작업의 특정한 별도 델리게이트를 사용하여 세션 델리게이트에 도달하기 전에 콜백을 가로챌 수 있습니다.

 

 

비동기성 그리고 URLSession

대부분 API네트워킹과 마찬가지로 URLSession API는 비동기입니다.

 

호출한 메서드에 따라 세가지 방식중 하나로 데이터를 반환합니다.

  • Swift를 사용한다면, 작업을 수행하기 위해 async 키워드를 표시한 메서드를 사용할 수 있습니다. 예를들어, 데이터를 가져오는 메서드인 data(from: delegate:)나 파일을 다운로드하는 download(from: delegate:)메서드가 있습니다. 호출지점에서 await 키워드를 사용하여 전송이 완료되기 전까지 일시정지합니다(suspend). 또한 bytes(from: delegate:)메서드를 사용하여 데이터를 AsyncSequence로 수신할 수 있습니다. 이 접근 방식은 for-await-in 구문을 사용하여 반복적으로 데이터를 수신하게 됩니다. URL 형식은 공유된 URL session에서 바이트나 라인을 가져오는 편리한 메서드도 제공합니다.
  • Swift나 Objective-C에서는 전송완료시 실행되는 완료 핸들러 블럭을 제공합니다.
  • Swift나 Objective-C에서는 전송이 진행되는 동안이나 전송이 완료된 직후에 델리게이트 메서드에 대한 콜백을 받을 수 있습니다.

 

델리게이트로 정보를 전달하는 것 외에도 URLSession은 상태와 진행 프로퍼티를 제공합니다.

작업의 현재상태를 기반으로 프로그래밍 방식으로 결정하는 경우 이러한 속성을 쿼리로 사용합니다.(상태는 언제든지 바뀔 수 있다는 경고와 함께)

 

 

프로토콜 지원

URLSession 클래스는 사용자의 시스템 기본 설정에 구성된대로 프록시 서버 및 SOCKS 게이트웨이를 투명하게 지원하여 데이터, 파일, ftp, http 그리고 https URL schemes를 기본적으로 지원합니다. (여기서 투명하게 지원하는 의미는 존재를 인식할 수 없는 의미로 사용된것 같다.프록시 서버 및 SOCKS 게이트웨이의 세부사항을 접근할 수 없다? 존재를 인식할 수 없다? 인 의미같다.)

URLSession은 HTTP/1.1, HTTP/2, HTTP/3 프로토콜을 지원합니다.

HTTP/2는 RFC7540에 설명된대로 ALPN을 지원하는 서버가 필요합니다.

또한 하나의 커스텀 네트워킹 프로토콜이나 URL schemes를 추가로 지원합니다.

이는 URLProtocol을 서브클래싱하여 지원합니다.

 

 

ATS 앱 전송 보안

iOS 9.0, macOS 10.11 이후의 최신버전까지는 URLSession으로 생성된 모든 HTTP연결은 ATS를 사용합니다.

ATS는 HTTP연결에서 HTTPS를 사용하도록 요구합니다.

추가적인 정보는 NSAppTransportSecurity에서 볼 수 있습니다.

 

 

기본적인 복사 동작

세션과 작업 객체는 아래와 같이 NSCopying 프로토콜을 따릅니다.

  • 세션이나 작업 객체를 복사할 때, 동일한 객체를 가져옵니다.
  • Configuration 객체를 복사할 때, 독립적으로 수정할 수 있는 새로운 복사본을 얻게 됩니다.

 

 

스레드 안정

URLSession API는 스레드안정적입니다.

모든 스레드 컨텍스트에서 세션과 작업을 자유롭게 생성할 수 있습니다.

델리게이트 메서드가 제공된 완료 핸들러를 호출할 , 작업은 자동으로 올바른 델리게이트 대기열에 예약됩니다.

'iOS' 카테고리의 다른 글

NotificationCenter  (0) 2025.02.20
iOS Combine  (0) 2025.02.19
Fetching website data into memory  (0) 2024.12.10
URL Loading System 번역  (2) 2024.12.10
SwiftGen 사용  (0) 2024.11.26

Fetching website data into memory

Receive data directly into memory by creating a data task from a URL session

  • URLSession에서 DataTask를 생성하여 데이터를 메모리로 직접 수신한다.

For small interactions with remote servers, you can use the URLSessionDataTask class to receive response data into memory (as opposed to using the URLSessionDownloadTask class, which stores the data directly to the file system)

  • 원격서버와 소규모 상호 작용의 경우 URLSessionDataTask 클래스를 사용하여 응답 데이터를 메모리로 수신할 수 있다.(데이터를 파일 시스템에 직접 저장하는 URLSessionDownloadTask 클래스를 사용하는 것과 반대로)

A data task is ideal for uses like calling a web service endpoint

  • 데이터 작업은 웹 서비스 엔드포인트 호출과 같은 사용에 이상적입니다.
  • 엔드포인트(Endpoint): 웹 애플리케이션에서 클라이언트가 서버에 요청을 보내는 특정 URL

You use a URL session instance to create the task

  • URLSession 인스턴스를 사용하여 작업을 만들 수 있다.

If your needs are fairly simple, you can use the shared instance of the URLSession class

  • 니즈가 꽤 단순하다면,  URLSession 클래스의 shared 인스턴스를 사용할 수 있다.

If you want to interact with the transfer through delegate callbacks, you’ll need to create a session instead of using the shared instance

  • Delegate 콜백들을 통한 전송과 상호작용 하려면, shared 인스턴스를 사용하는 대신 세션을 생성해야 한다.

You use a URLSessionConfiguration instance when creating a session, also passing in a class that implements URLSessionDelegate or one of its subprotocols

  • 세션을 생성할 때 URLSessionConfiguration 인스턴스를 사용하고 URLSessionDelegate 또는 해당 하위 프로토콜 중 하나를 구현하는 클래스도 전달한다.

Sessions can be reused to create multiple tasks, so far each unique configuration you need, create a session and store it as a property

  • 세션은 여러 작업을 만드는데 재사용 될 수 있으므로 필요한 고유한 구성마다 세션을 만들고 속성으로 저장합니다.

Note

  • Be careful to not create more sessions than you need
  • For Example, if you have several parts of your app that need a similarly configured session, create one session and share it among them
  • 필요 이상의 session을 만들지 않도록 주의하세요.
  • 예를 들어, 앱의 여러 부분에서 유사하게 구성된 세션이 필요한 경우, 하나의 세션을 만들고 공유하도록 하세요.

Once you have a session, you create a data task with one of the dataTask() methods

  • 세션이 있다면, dataTask()메서드들 중 하나를 사용하여 데이터 작업을 생성합니다.

Tasks are created in a suspended state, and can be started by calling resume()

  • 작업들은 일시 정지 상태에서 생성되고, resume()호출과 함께 시작됩니다.

 

Receive results with a completion handler

The simplest way to fetch data is to create a data task that uses a completion handler

  • 데이터를 받는 간단한 방법은 완료 핸들러를 사용한 데이터 작업을 생성하는 것 입니다.

With this arrangement, the task delivers the server’s response, data, and possibly errors to a completion handler block that you provide

  • 이 방식을 사용하면, 작업이 서버의 응답이나 데이터, 가능한 에러들을 제공된 완료 핸들러 블럭으로 전달합니다.

Shows the relationship between a session and a task, and how results are delivered to the completion handler.

  • 세션과 작업 사이의 관계도를 보여주고 결과가 어떻게 완료 핸들러로 배달되는지를 보여줍니다.

To create a data task that uses a completion handler, call the dataTask(with:) method of URLSession

  • 완료핸들러를 사용하여 데이터 작업을 생성하기 위해,URLSession의 dataTask(with:) 메서드를 호출합니다.

 

Your completion handler needs to do three things:

  1. Verify that the error parameter is nil. If not, a transport error has occurred; handle the error and exit.
  2. Check the response parameter to verify that the status code indicates success and that the MIME type is an expected value. If not, handle the server error and exit.
  3. Use the data instance as needed.
  • 완료 핸들러는 3가지를 충족합니다.
  • 1. 에러 파라미터가 nil인지 검증합니다. 만약 아니라면, 통신 오류가 발생됩니다. 에러를 대응하고 종료합니다..
  • 2. 응답 파라미터를 확인합니다. 상태 코드가 성공을 나타내는지, 그리고 MIME 형식이 기대된 값과 맞는지 검증합니다. 만약 아니라면 서버 에러를 대응하고 종료합니다.
  • 3. 필요한 데이터 인스턴스를 사용합니다.
  • MIME 형식이란 문서, 파일 또는 바이트 집합의 성격과 형식을 나타낸다.
  • 메세지 내부에 다른 파일을 전송할 수 있도록 하는 전자메일 프로토콜

 

Listing 1 shows a startLoad() method for fetching a URL’s contents.

  • 그림 1은 URL의 콘텐츠를 가져오기 위한 startLoad() 메서드를 보여줍니다.

It starts by using the URLSession class’s shared instance to create a data task that delivers its results to a completion handler.

  • 결과를 완료 핸들러로 전달하는 데이터 작업을 생성하기 위해 URLSession 클래스의 shared 인스턴스를 사용하면서 시작합니다.

After checking for local and server errors, this handler convert the data to a string, and uses it to populate a WKWebView outlet.

  • 로컬과 서버의 에러들을 확인한 후, 핸들러는 데이터를 문자열로 변환합니다. 그리고 이를 사용하여 WKWebView를 채웁니다.

Of course, your app might have other uses for fetched data, like parsing it into a data model.

  • 물론, 앱이 가져온 데이터를 다른 곳에 사용할 수 있습니다. (데이터 모델로 파싱하는 것과 같은)

Listing 1 Creating a completion handler to receive data-loading results

  • 그림 1: 데이터 로딩 결과를 받는 완료 핸들러를 생성
func startLoad() {
    let url = URL(string: "https://www.example.com/")!
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            self.handleClientError(error)
            return
        }
        guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
            self.handleServerError(response)
            return
        }
        if let mimeType = httpResponse.mimeType, mimeType == "text/html",
            let data = data,
            let string = String(data: data, encoding: .utf8) {
            DispatchQueue.main.async {
                self.webView.loadHTMLString(string, baseURL: url)
            }
        }
    }
    task.resume()
}

 

Important

The completion handler is called on a different Grand Central Dispatch queue than the one that created the task. Therefore, any work that uses data or error to update the UI — like updating webView — should be explicitly placed on the main queue, as shown here

  • 중요
  • 완료 핸들러는 작업이 생성된 곳과 다른 GCD queue에서 호출됩니다.
  • 그러므로 데이터나 에러를 사용하여 UI를 업데이트 하는 모든 작업은 위에 예시처럼 명시적으로 메인 큐에서 배치해야합니다.

 

Receive transfer details and results with a delegate

  • Delegate를 통한 전송 세부 정보 및 결과를 받아보세요.

For a greater level of access to the task’s activity as it proceeds, when creating the data task, you can set a delegate on the session, rether than providing a completion handler.

  • 진행되는 작업 활동보다 더 높은 수준의 액세스를 위해 데이터 작업을 생성할 때 완료 핸들러를 제공하는 대신 세션에 delegate를 설정할 수 있습니다.

Shows this arrangement

With this approach, portions of the data are provided to the urlSession( : dataTask: didReceive: ) method of URLSessionDataDelegate as they arrive, until the transfer finishes or fails with an error.

  • 이러한 접근방식을 사용하면, 전송이 완료되거나 오류로 인해 실패할 때까지 데이터의 일부가 도착하는대로 URLSessionDataDelegate의 urlSession(: dataTask: didReceive: ) 메서드를 통해 데이터가 제공됩니다.

The delegate also receives other kinds of events as the transfer proceeds.

  • delegate는 전송이 진행됨에 따라 다른 종류의 이벤트들도 수신합니다.

You need to create your own URLSession instance when using the delegate approach, rather than using the URLSession class’s simple shared instance.

  • Delegate 방식을 사용할 땐, URLSession 클래스의 간단한 shared 인스턴스를 사용하는 것 보다 자신만의 URLSession 인스턴스를 생성할 필요가 있습니다.

Creating a new session allows you to set your own class as the session’s delegate, as shown in Listing 2.

  • 새로운 세션을 생성하는 것은 그림 2와 같이 자신만의 클래스를 세션의 delegate로 설정할 수 있습니다.

Declare that your class implements one or more of the delegate protocols(URLSessionDelegate, URLSessionTaskDelegate, URLSessionDataDelegate, and URLSessionDownloadDelegate)

  • 하나이상의 delegate 프로토콜을 구현한 클래스를 정의하세요.(URLSessionDelegate, URLSessionTaskDelegate, URLSessionDataDelegate, 그리고 URLSessionDownloadDelegate)

Then create the URL session instance with the initializer init(configuration: delegate: delegateQueue: )

  • 그다음 생성자를 통해 URLSession 인스턴스를 생성하세요. (Configuration: delegateL delegateQueue: )

You can customize the configuration instance used with this initializer

  • 생성자를 통해 configuration 인스턴스를 커스터마이징할 수 있습니다.

For example, it’s a good idea to set waitsForConnectivity to true.

  • 예를들어, waitsForConnectivity를 true로 설정하는 것이 좋습니다.

That way, the session waits for suitable connectivity, rather than failing immediately if the required connectivity is unavailable.

이렇게 하면 필요한 연결을 사용할 수 없는 경우 세션이 즉시 실패하지 않고 적절한 연결을 기다립니다.

 

Listing 2 Creating a URLSession that uses a delegate

private lazy var session: URLSession = {
    let configuration = URLSessionConfiguration.default
    configuration.waitsForConnectivity = true
    return URLSession(configuration: configuration,
                      delegate: self, delegateQueue: nil)
}()

 

Listing 3 shows a startLoad() method that uses this session to start a data task, and uses delegate callbacks to handle received data and errors.

  • 그림 3은 데이터 작업을 시작하는 세션을 사용하고 전달받은 데이터와 에러들을 핸들링하는 delegate 콜백을 사용하는 startLoad() 메서드를 보여줍니다.

This listing implements three delegate callbacks:

  • urlSession( :dataTask :didReceive: completionHandler: ) verifies that the response has a successful HTTP status code, and that the MIME type is text/html or text/plain. If either of these is not the case, the task is canceled otherwise it’s allowed to proceed
  • urlSession( : dataTask :didReceive: ) takes each Data instance received by the task and appends it to a buffer called receivedData.
  • urlSession( :task :didCompleteWithError: ) first looks to see if a transport-level error has occurred. If there is no error, It attempts to convert the receivedData buffer to a string and set it as the contents of webView.
  • urlSession( :dataTask :didReceive :compeltionHandler: )는 응답이 성공 HTTP 상태 코드를 갖고 있는지, MIME 형식이 text/html 혹은 text/plain 인지 검증합니다. 둘 중 하나라도 해당되지 않는다면 작업이 취소되고 그렇지 않으면 게속 진행됩니다.
  • urlSession( :dataTask :didReceive: )는 작업에서 수신한 각 Data 인스턴스를 받고, receivedData로 호출된 버퍼에 저장됩니다.
  • urlSession( :task :didCompleteWithError:)은 먼저 전송 수준 오류가 발생했는지 확인합니다. 에러가 없다면 receivedData 버퍼를 문자열로 변환하여 webView의 컨텐츠로 설정하도록 시도합니다.

 

Listing 3 Using a delegate with a URL session data task

var receivedData: Data?


func startLoad() {
    loadButton.isEnabled = false
    let url = URL(string: "https://www.example.com/")!
    receivedData = Data()
    let task = session.dataTask(with: url)
    task.resume()
}


// delegate methods


func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse,
                completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
    guard let response = response as? HTTPURLResponse,
        (200...299).contains(response.statusCode),
        let mimeType = response.mimeType,
        mimeType == "text/html" else {
        completionHandler(.cancel)
        return
    }
    completionHandler(.allow)
}


func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    self.receivedData?.append(data)
}


func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    DispatchQueue.main.async {
        self.loadButton.isEnabled = true
        if let error = error {
            handleClientError(error)
        } else if let receivedData = self.receivedData,
            let string = String(data: receivedData, encoding: .utf8) {
            self.webView.loadHTMLString(string, baseURL: task.currentRequest?.url)
        }
    }
}

 

The various delegate protocols offer methods beyond those shown in the above code, for handling authentication challenges, following redirects, and other special cases.

  • 다양한 delegate 프로토콜은 현재 코드에서 보여주는 것보다 더 많은 메서드들을 제공합니다. 인증 문제 처리, 리디렉션 추적, 기타 특수 사례 등등

Using a URL Session, in the URLSession discussion, describes the various callbacks that may occur during a transfer.

  • URLSession 토론에서 URLSession 사용은 전송중에 발생하는 다양한 콜백을 설명합니다

'iOS' 카테고리의 다른 글

iOS Combine  (0) 2025.02.19
URLSession 번역  (0) 2024.12.13
URL Loading System 번역  (2) 2024.12.10
SwiftGen 사용  (0) 2024.11.26
[iOS][버그해결] 이중으로 들어간 CollectionViewCell안 CollectionViewCell이 재사용되는 버그  (0) 2024.11.16

https://developer.apple.com/documentation/foundation/url_loading_system

 

URL Loading System | Apple Developer Documentation

Interact with URLs and communicate with servers using standard Internet protocols.

developer.apple.com

 

URL Loading System

Interact with URLs and communicate with servers using standard Internet protocols

  • 표준 인터넷 프로토콜을 사용하여 URL과 상호작용하고 서버와 통신합니다.

The URL Loading System provides access to resources identified by URLs, using standard protocols like https or custom protocols you create

  • URL Loading System은 https나 사용자 정의 프로토콜과 같은 표준 프로토콜을 사용하여 URL로 식별된 리소스에 대한 접근을 제공합니다.

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

  • URLSession 인스턴스를 사용하여 하나 이상의 URLSessionTask 인스턴스를 생성할 수 있습니다.
  • URLSessionTask 인스턴스는 데이터를 앱으로 가져오고 반환하고, 파일을 다운로드하거나 데이터와 파일을 원격 위치로 전송 할 수 있습니다.

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

  • session을 구성하기 위해 URLSessionConfiguration 객체를 사용합니다.
  • URLSessionConfiguration으로 셀룰러 네트워크에서의 연결 허용 여부나 캐시 및 쿠키 사용 방법 같은 동작을 제어할 수 있다.

You can use one session repeatedly to create tasks.

  • 하나의 session을 반복적으로 사용하여 작업(task)을 생성할 수 있다.

For example, a web browser might have separate sessions for regular and private browsing use, where the private session doesn’t cache its data

  • 예를 들어, 웹 브라우저는 일반 브라우징과 비공개 브라우징 사용을 위한 별도의 session이 있을 수 있다. 비공개 session은 해당 데이터를 캐시하지 않는다.

Figure 1 shows how two sessions with these configurations can then create multiple tasks

  • 그림 1은 이러한 구성을 갖는 두 세션이 어떻게 여러 작업을 생성할 수 있는지 보여준다.

Each session is associated with a delegate to receive periodic updates (or errors)

  • 각 세션은 정기적인 업데이트를 수신하기 위해 delegate와 연결된다.

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

  • 기본 delegate는 사용자가 제공하는 완료 핸들러를 호출한다. 자신만의 사용자 정의 delegate를 제공하는것을 선택했다면 이 블럭은 호출되지않는다.

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

  • 백그라운드에서 실행되도록 세션을 구성하면 앱이 일시 중지되고 시스템이 대신 데이터를 다운로드하고 앱을 깨워 결과를 전달할 있다.

+ Recent posts