Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- uitableview
- 리팩토링
- MVVM
- Refactoring
- UITextView
- Xcode
- rxswift
- SWIFT
- map
- ios
- swiftUI
- 스위프트
- combine
- 클린 코드
- Protocol
- ribs
- RxCocoa
- HIG
- 리펙토링
- Clean Code
- uiscrollview
- 애니메이션
- Human interface guide
- Observable
- swift documentation
- collectionview
- clean architecture
- UICollectionView
- tableView
- 리펙터링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. Multipart, 멀티파트 - BackgroundSession 사용 방법 (background에서 업로드, suspended에서 업로드, not running에서 업로드, getTasksWithCompletionHandler) 본문
iOS 응용 (swift)
[iOS - swift] 3. Multipart, 멀티파트 - BackgroundSession 사용 방법 (background에서 업로드, suspended에서 업로드, not running에서 업로드, getTasksWithCompletionHandler)
jake-kim 2023. 7. 3. 02:201. Multipart, 멀티파트 - 개념 (메모리 효율성, 네트워크 대역폭, 개별적 재전송 유리)
2. Multipart, 멀티파트 - URLSession으로 구현 (uploadTask, URLSessionUploadTask, progress 처리)
3. Multipart, 멀티파트 - BackgroundSession 사용 방법 (background에서 업로드, suspended에서 업로드, not running에서 업로드, getTasksWithCompletionHandler)
BackgroundSession 이란?
- URLSession 인스턴스를 생성할 때 URLSessionConfiguration를 사용하여 캐시 정책, 타임아웃 지정이 가능한데 여기서 background session 컨피그로 설정한 것
- URLSessionConfiguration에 관한 구체적인 내용은 이 포스팅 글에서 확인
- BackgroundSession으로 설정하면 default 컨피그와 동일하게 7일 timeout으로 지정됨 (timeoutIntervalForResponse)
- timeoutIntervalForResponse값은 언제든 변경 가능
let configuration = URLSessionConfiguration.background(withIdentifier: "test")
print(configuration.timeoutIntervalForResource) // 604800초 = 7일
BackgroundSession 동작 이해하기
- background session은 별도의 프로세스에서 전송을 처리되는 시스템
- iOS 앱 자체가 일시 중단되거나 종료된 경우, 앱을 다시 켰을때 재전송이 기능
- iOS 앱이 시스템에 의해 종료되고 다시 시작되면 앱은 identifier로 구분하여 session을 다시 생성한 후 종료 시점에 진행 중이던 전송 상태를 검색하여 다시 재개가 가능
- 단, 시스템에서 앱을 정상적으로 종료하는 경우만 적용
- 사용자가 멀티태스킹 화면에서 앱을 종료하면 시스템은 세션의 백그라운드 전송을 모두 취소하므로 주의
- 시스템은 사용자가 강제로 종료한 앱을 자동으로 다시 시작하지 않음 (전송을 다시 시작하려면 사용자가 명시적으로 앱을 다시 시작해야함)
BackgroundSession을 사용하여 이미지 업로드하기
- 이전 포스팅 글에서 알아본 대로 멀티파트 방식을 사용하기 위해 body부분에 특정 형태의 문자열을 채워넣기
- backgroundSession을 사용하는 부분은 URLSession.shared를 사용하지 않고 URLSession을 만들때 background 컨피그를 사용한다는것만 차이
func uploadImageUsingURLSession(imageData: Data, completion: @escaping (Error?) -> Void) {
let url = URL(string: "https://example.com/upload")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
let uniqString = UUID().uuidString
let contentType = "multipart/form-data; boundary=\(uniqString)"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
var body = Data()
body.append("--\(uniqString)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n".data(using: .utf8)!)
body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
body.append(imageData)
body.append("\r\n".data(using: .utf8)!)
body.append("--\(uniqString)--\r\n".data(using: .utf8)!)
let session = URLSession(configuration: .background(withIdentifier: id))
let task = session.uploadTask(with: request, from: body) { (data, response, error) in
DispatchQueue.main.async {
if let error = error {
completion(error)
return
}
// 응답 처리
completion(nil)
}
}
task.delegate = self
task.resume()
}
사용자가 앱 종료하고 다시 앱 실행 시킨 경우, 재개하기
- backgroundSession을 만들 때의 id를 똑같이하여 session을 생성
- backgroundSession에서만 id값을 필수로 입력하도록 인터페이스를 가지고 있는 이유는 이처럼 작업을 다시 재개할 수 있도록 하기 위함
- session의 메소드인 getTasksWithCompletionHandler 사용
let configuration = URLSessionConfiguration.background(withIdentifier: "test_id")
let session = URLSession(configuration: configuration)
// 이전에 실행했던 이미지 업로드 작업을 확인하고 처리
session.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) in
// uploadTasks에서 이전에 실행한 업로드 작업을 찾아서 처리
}
- getTasksWithCompletionHandler 클로저 부분에서는 단순히 url을 비교하고 resume이나 calcel처리
session.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) in
for task in uploadTasks {
if let originalRequest = task.originalRequest, let url = originalRequest.url {
if url.absoluteString == "<이전에 실행한 업로드 작업의 URL>" {
// 이전에 실행한 업로드 작업을 찾았을 때, 원하는 처리를 수행
// 예를 들어, 업로드 작업을 이어서 진행하거나, 작업을 취소하고 처음부터 다시 시작할 수 있습니다.
// task.resume() // 업로드 작업 이어서 진행
// task.cancel() // 업로드 작업 취소
}
}
}
}
정리
- 사용자가 background로 갔을때도 계속 파일을 업로드나 다운로드 하고 싶은 경우 backgroundSession을 사용
- 사용자가 앱 종료 후 다시 앱을 실행한 경우에도 backgroundSession을 사용했었다면 같은 identifer로 session을 만들면 이전 URLSessionTask 인스턴스를 획득이 가능 (그러므로 이전 task 들의 resume, cancel이 가능)
cf) 업로드 말고, 다운로드 하는 URLSessionDownloadTask를 사용하고 싶은 경우 이 포스팅 글 참고
* 전체 코드: https://github.com/JK0369/ExBackgroundSession
* 참고
https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1407496-background
https://developer.apple.com/documentation/foundation/urlsessionconfiguration
'iOS 응용 (swift)' 카테고리의 다른 글
Comments