@@ -22,38 +22,50 @@ typealias GIDImage = NSImage
2222
2323import Combine
2424import SwiftUI
25- import GoogleSignIn
25+ @ preconcurrency import GoogleSignIn
2626
2727/// An observable class for loading the current user's profile image.
28- final class UserProfileImageLoader : ObservableObject {
28+ @ MainActor final class UserProfileImageLoader : ObservableObject {
2929 private let userProfile : GIDProfileData
30- private let imageLoaderQueue = DispatchQueue ( label : " com.google.days-until-birthday " )
30+ private var imageLoadingTask : Task < Void , Never > ?
3131 /// A `UIImage` property containing the current user's profile image.
3232 /// - note: This will default to a placeholder, and updates will be published to subscribers.
3333 @Published var image = GIDImage ( named: " PlaceholderAvatar " ) !
3434
3535 /// Creates an instance of this loader with provided user profile.
3636 /// - note: The instance will asynchronously fetch the image data upon creation.
37- init ( userProfile: GIDProfileData ) {
38- self . userProfile = userProfile
39- guard userProfile. hasImage else {
40- return
37+ init ( userProfile: GIDProfileData ) {
38+ self . userProfile = userProfile
39+ guard userProfile. hasImage else {
40+ return
41+ }
42+ imageLoadingTask = Task {
43+ await loadProfileImage ( )
44+ }
4145 }
4246
43- imageLoaderQueue. async {
44- #if os(iOS)
45- let dimension = 45 * UIScreen. main. scale
46- #elseif os(macOS)
47- let dimension = 120
48- #endif
49- guard let url = userProfile. imageURL ( withDimension: UInt ( dimension) ) ,
50- let data = try ? Data ( contentsOf: url) ,
51- let image = GIDImage ( data: data) else {
52- return
53- }
54- DispatchQueue . main. async {
55- self . image = image
56- }
47+ private func loadProfileImage( ) async {
48+ #if os(iOS)
49+ let dimension = 45 * UIScreen. main. scale
50+ #elseif os(macOS)
51+ let dimension = 120
52+ #endif
53+
54+ guard let url = userProfile. imageURL ( withDimension: UInt ( dimension) ) else {
55+ return
56+ }
57+
58+ do {
59+ let ( imageData, _) = try await URLSession . shared. data ( from: url)
60+ if let image = GIDImage ( data: imageData) {
61+ self . image = image
62+ }
63+ } catch {
64+ print ( " Image download failed: " , error)
65+ }
66+ }
67+
68+ deinit {
69+ imageLoadingTask? . cancel ( )
5770 }
58- }
5971}
0 commit comments