0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

昨日はTaskのsleepが実際に役立つコードを書いたので、今日はTaskのsleepについて深堀りしてみるよ

0
Last updated at Posted at 2026-04-10

コードはこちら

//
//  ContentView.swift
//  SwiftUIShape
//
//  Created by tsu-na-gu on 2026/04/10.
//

import SwiftUI

struct ContentView: View {
    private var purpleGradient = LinearGradient(gradient: Gradient(colors: [Color(red: 207/255, green: 150/255, blue: 207/255), Color(red: 107/255, green: 116/255, blue: 179/255)]), startPoint: .trailing, endPoint: .leading)
    @State private var progress = 0.0
    var body: some View {
        VStack {
            ZStack {
                Circle()
                    .stroke(Color(.systemGray6), lineWidth: 20)
                    .frame(width: 300, height: 300)
                
                Circle()
                    .trim(from:0.0, to: progress)
                    .stroke(purpleGradient, lineWidth: 20)
                    .frame(width: 300, height: 300)
                    .rotationEffect(.degrees(-90))
                    .overlay {
                        VStack {
                            Text("\(Int(progress * 100))%")
                                .font(.system(size: 80, weight: .bold, design: .rounded))
                                .foregroundColor(.gray)
                            Text("Complete")
                                .font(.system(.body, design: .rounded))
                                .bold()
                                .foregroundColor(.gray)
                        }
                    }
                
            }
            .padding(100)
            Button {
                Task {
                    await progressStart()
                }
            } label: {
                Label("Start", systemImage: "play.circle")
                    .foregroundStyle(.white)
            }
            .buttonStyle(.borderedProminent)
        }
    }
    private func progressStart() async {
        progress = 0.0
        
        for i in 0...100 {
            try? await Task.sleep(for: .milliseconds(80))
            withAnimation(.linear(duration: 0.08)) {
                progress = Double(i) / 100.0
            }
        }
    }
}


    

#Preview {
    ContentView()
}

学習ソースはこちら、$20月で開設ビデオが見られるよ

sleepのtolaranceパラメータの意味についてCaludeの回答

Task.sleepのtoleranceパラメータは、主に電力効率の最適化のために機能します。具体的に効果を発揮するのは以下のような場合です:
toleranceが機能する状況

  1. 複数のタイマーイベントがある場合
    swift// 例:複数のタスクが近い時間にスリープしている
    Task {
    try await Task.sleep(for: .seconds(3), tolerance: .seconds(1))
    // 処理A
    }

Task {
try await Task.sleep(for: .seconds(3.5), tolerance: .seconds(1))
// 処理B
}
システムはこれらを「まとめて」起動できます(3〜4秒の範囲内で両方を処理)
2. デバイスが低電力状態の場合

iOSデバイスがバックグラウンド状態
Macがアイドル状態でCPUが低電力モードに入っている
→ toleranceがあることで、システムは効率的なタイミングでCPUを起こせます

  1. バッテリー駆動時
    モバイルデバイスで特に効果的。CPUのウェイクアップ回数を減らすことで電力消費を抑えます。
    toleranceがあまり意味を持たない場合

CPUが常にアクティブ:ゲームや動画再生中など
単独のタイマーのみ:他にスケジュールされたイベントがない
短時間のスリープ:数ミリ秒程度の場合

実用的な使い分け
swift// 正確なタイミングが必要な場合
try await Task.sleep(for: .seconds(3), tolerance: .zero)

// 電力効率を優先する場合(推奨)
try await Task.sleep(for: .seconds(3), tolerance: .seconds(1))
つまり、toleranceは「このくらいズレても構わない」という余裕をシステムに与えることで、システムが賢く電力管理できるようにする仕組みです。特にバックグラウンド処理や定期的なタスクで効果を発揮します。

続いてTaskは代入先にresultで取得できるenum型を代入することを確認

//
//  main.swift
//  TaskSleep
//
//  Created by tsu-na-gu on 2026/04/10.
//

import Foundation

//try await Task.sleep(for: .seconds(3), tolerance: .seconds(1))

enum LocalError: Error {
    case fetchFailed, decodeFailed
}

func fetchQuotes() async {
    let downlodadTask = Task {
        let url = URL(string: "https://hws.dev/quotes.txt")!
        
        
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            
            if let string = String(data: data, encoding: .utf8) {
                return string
            } else {
                throw LocalError.decodeFailed
            }
        } catch {
            throw LocalError.fetchFailed
        }
    }
    
    let result = await downlodadTask.result
    
    switch result {
    case .success(let string):
        print(string)
    case .failure(let error):
        print("Error occured: \(error)")
    }
}

result.get()をするとエラーが再スローされるのでハンドリングしてもよし

//
//  main.swift
//  TaskSleep
//
//  Created by tsu-na-gu on 2026/04/10.
//

import Foundation

//try await Task.sleep(for: .seconds(3), tolerance: .seconds(1))

enum LocalError: Error {
    case fetchFailed, decodeFailed
}

func fetchQuotes() async {
    let downlodadTask = Task {
        let url = URL(string: "https://hws.dev/quotes.txt")!
        
        
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            
            if let string = String(data: data, encoding: .utf8) {
                return string
            } else {
                throw LocalError.decodeFailed
            }
        } catch {
            throw LocalError.fetchFailed
        }
    }
    
    let result = await downlodadTask.result
    
    do {
        let string = try result.get()
        print(string)
    } catch LocalError.fetchFailed {
        print("Unable to fetch the quotes.")
    } catch LocalError.decodeFailed {
        print("Unable to convert data to text.")
    } catch {
        print("unknown error.")
    }

さらにエラーの種類が問題にならないなら、try?でnil代入して早期returnしても構わない

func processQuotes() async {
    let downloadTask = Task {
        let url = URL(string: "https://hws.dev/quotes.txt")!
        let (data, _) = try await URLSession.shared.data(from: url)
        
        guard let string = String(data: data, encoding: .utf8) else {
            throw LocalError.decodeFailed
        }
        
        return string
    }
    
    let result = await downloadTask.result
    
    // try? でOptionalに変換
    guard let string = try? result.get() else {
        print("Failed to fetch quotes")
        return  // 早期リターン
    }
    
    print(string)  // 成功パス
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?