본문 바로가기

STUDY/기타

NSUrlSession (1) - IOS의 다운로더 만들기

오늘은 NSURLSession 에 대해 포스팅을 해 보겠습니다. 

애플은 문서가 매우매우 불친절한 경향이 있는데요,, ㅠㅠ 최대한 알기쉽게 설명을 해 보려고 합니다.

제가 삽질하며 알게된 내용들도 함께 포스팅 하였으니 혹시 잘못된 정보가 있다면 꼭꼭 댓글 부탁드립니다!! 

 

 

 

앱에서 서버로부터 파일을 받아 로컬에 저장할 때 보통은 HTTP요청으로 받아옵니다. 

이러한 요청을 편리하게 해주는 기능인 NSURLSession은 Apple에서 제공됩니다. 

참 좋은 기능이죠  :-0

 

 

 

 

 

위 그림은 NSURLSession을 설명하는 그림인데 저도 인터넷에서 퍼왔습니다..^^ 

 

 

그림의 설명이 복잡하게 보이지만 간단히 설명하면 

NSURLSession은 HTTP요청을 편리하게 해주는 객체이며 여러 종류의 Configuration중 한 종류를 생성하여 사용자가 상황에 맞게 사용할 수 있도록 제공됩니다.

 

1. defaultSessionConfiguration(기본세션)

: 디폴트 configuration 객체를 생성합니다. 사용자들은 disk-persisted global chache, credential, cookie storage objects를 사용하게 됩니다.
2. ephemeralSessionConfiguration

: 디폴트 configuration과 유사합니다. 유일한 차이점은 세션관련 데이터가 메모리에 올라가있다는 것입니다. private 세션이라고 생각하시면 되겠습니다.
3. backgroundSessionConfiguration:

세션이 백그라운드에서 다운로드 작업과 업로드 작업을 수행할 수 있도록 합니다. 이 데이터 전송작업은 앱이 Suspended나 Not running일 때에도 수행됩니다.

 

 

// 초기화 작업
-(void) viewDidLoad
{
	...
    NSURLSessionConfiguration* configuration = 
    			[NSURLSessionConfiguration backgroundSessionConfiguration:@"com.eunbiroun.com"];
    configuration.allowCellularAccess = YES;
    
    _session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    
}

 

처음에 앱이 뜰때 세션 초기화를 통해 세션을 만들어줍니다. 

 

새로운 세션을 생성햇으면 이제 Task를 생성해서 넣어줍니다.

세션을 구현할 때 주의해야 할 점은 세션은 한 프로세스에 여러개가 생성될 수는 있지만,

세션이 여러개가 생성되면 처리 속도가 그만큼 느려지기 때문에 세션을 늘리는것은 권장되지 않는다는 점을 꼭 숙지하셔야 합니다. 

 

 

 

 

 

 

NSURLSession의 task는 정말 다양한 종류가 있습니다. 

 

- NSURLSessionTask

URL 세션에서 수행되는 특정 리소스 다운로드와 같은 작업.

- NSURLSessionDataTask

다운로드 한 데이터를 메모리의 앱으로 직접 반환하는 URL 세션 작업입니다.

- NSURLSessionDownloadTask

다운로드 한 데이터를 파일로 저장하는 URL 세션 작업입니다.

- NSURLSessionUploadTask

요청 본문에서 네트워크에 데이터를 업로드하는 URL 세션 작업입니다.

- NSURLSessionStreamTask

스트림 기반 URL 세션 작업.

 

상황에 맞는 Task를 골라 사용하시면 됩니다.

Task 종류 관련 참고문헌 : https://developer.apple.com/documentation/foundation/nsurlsession?language=objc

 

NSURLSession - Foundation | Apple Developer Documentation

Empties all cookies, caches and credential stores, removes disk files, flushes in-progress downloads to disk, and ensures that future requests occur on a new socket.

developer.apple.com

 

 

 

 

 

NSURLSessionTask와 HTTP Request는 1:1로 매칭된다고 생각해 주시면 되며, URL 한개 당 task 1개를 생성합니다.

 

이렇게 생성된 NSURLSessionTask들은 생명주기를 지니게 됩니다. 

위에 보시는것처럼 SessionTask에는 cancel, resume, suspend로 작업을 취소, 시작,일시중지 할 수 있도록 되어있습니다.

처음에 Task가 생성되면 일시정지 된 상태로 생성이 되며 시작을 하려면 꼭 resume call을 해 주어야 합니다. 

 

 

NSURL *downloadURL = [NSURL URLWithString:DownloadString];
// 1. URL로 새로운 요청을 생성합니다. 
NSURLRequest*request = [NSURLRequest requestWithURL:downloadURL];

// 2. 세션에 request를 요청후 downloadTask를 얻어냅니다.
_downloadTask = [self.session downloadTaskWithRequest];

// 3. downloadTask는 정지상태로 생성됩니다. resume을 꼭 불러주어야 시작됩니다. 
[_downloadTask resume];

 

 

 

위와같이 시작된 task는 다운로드가 완료되기 전까지 cancel과 suspend로 취소, 일시정지를 할 수 있고 

다운로드 중이던 데이터를 저장했다가, 나중에 다운로드 받은곳부터 다시 시작할 수도 있습니다. 

 

제가 suspend를 사용해본 결과 여러가지 단점이 있었습니다.

짧은 시간만 일시정지가 가능했고, 일부 task만 일시정지하는것이 불가능 했습니다.

(그럴거면 뭐하러 task단위로 suspend가 있는것이지 ?........) 

 

suspend를 구현이 너무너무 하고싶어서! 찾아본 결과 아래와 같은 함수를 사용할 수 있었습니다. 

뚜둥.. 

 

 

- (void)cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler; 

Cancels a download and calls a callback with resume data for later use. 

출처: https://developer.apple.com/documentation/foundation/nsurlsessiondownloadtask/1411634-cancelbyproducingresumedata?language=objc 

 

 

-(void)suspendAndSaveData()
{
	[task cancelByProducingResumeData:(^)(NSData *resumeData)
    {
		//저장하던 데이터 수동저장 
        _resumeData = resumeData;
	}
}

-(BOOL)restartDownload
{
	if(nil == _resumeData)
	{
    	return NO;
    }
    
	[_resumeData resume];
    return YES;
}

 

사용법은 위처럼 사용하면 되겠습니다.

제 코드들은 컴파일러에서 컴파일 후 복붙한것이 아니라 코드블럭에서 짠 것이므로 컴파일 에러가 발생할 확률이 매우매우 높습니다!!! 참고만 부탁드립니다 ... 

 

 

cancle은 다행히도 잘 동작해 주었습니다. 

하지만 이미 돌아가고 있던 task들은 cancel이 호출이 된 후에도 완료되어 finish 처리가 될 수 있다는 점을 기억해 두셔야 하겠습니다. 

 

 

 

 

 

나머지 완료처리는 2탄에서 마저 포스팅하겠습니다~! 

 

 

'STUDY > 기타' 카테고리의 다른 글

Reducing Texture Memory Usage ( by Two Channel Color Encoding )  (0) 2021.09.02
Simplygon SDK 7.1 Docs (2)  (0) 2019.09.01
Simplygon SDK 7.1 Docs  (0) 2019.08.18