The operation couldn’t be completed. User has denied activities for this target: What does this mean? (SwiftUI)

43 Views Asked by At

I'm trying to run Live Activities and Dynamic Island activities on my actual iPhone 15 Pro Max (Not the simulated iPhone). However, when I run the app, I get the error The operation couldn’t be completed. User has denied activities for this target. As you scroll, you'll see where I'm having the issue. What should I do?

 import SwiftUI
import WidgetKit
import Foundation
import ActivityKit

struct HomeView: View {
    
    @State private var currentTime = Date()
    
    var body: some View {
    NavigationView {
        ScrollView {
            VStack {
                
                
                ZStack { // No need to specify alignment here for individual items
                    Image("TrexlerLibraryPicture")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                    
                    VStack {
                        Text(libraryClosingText())
                            .foregroundColor(.white)
                            .padding([.top, .leading]) // Adds padding to the top and leading sides, moving the text towards the top left
                            .font(.title2)
                            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)// Aligns text to the top leading edge
                            
                        
                        Spacer() // Pushes both texts to their respective edges
                        
                        Text("Welcome Emanuel!")
                            .foregroundColor(.white)
                            .padding([.bottom, .leading]) // Adds padding to the bottom and leading edges
                            .font(.title)
                            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomLeading) // Aligns to bottom leading
                    }
                }
                .navigationTitle("Home")
               
              // LOOK HERE! IT'S THIS CODE!!!
            }.onAppear() {
                do {
                        _ = try LiveActivityManager.startActivity(timeRemaining: calculateTimeRemaining())
                    print("Hello, it made it ")
                    }
                catch {
                    print(error
                        .localizedDescription)
                }
            }
        
            
            .onReceive(Timer.publish(every: 60, on: .main, in: .common).autoconnect()) { _ in
                                // This block is executed every minute
                                self.currentTime = Date() // Update the current time
                            }
            
            VStack {
                HStack {
                    
                    ServiceTiles(tile: ServiceTile(picture: "DeSalesLibraryE-Resources", title: "How to Guide"))
                    ServiceTiles(tile: ServiceTile(picture: "BookaStudyRoom", title: "Book a Study Room"))
                }
            }
            
            Spacer()
            VStack {
                HStack {
                    ServiceTiles(tile: ServiceTile(picture: "LibraryBookTech", title: "Book Technology"))
                    ServiceTiles(tile: ServiceTile(picture: "library3dmodel", title: "Book 3D Anatomical Model"))
                }
            }
            
            Spacer()
            VStack {
                HStack {
                    ServiceTiles(tile: ServiceTile(picture: "IntLoanArticleReqPicture", title: "Interlibrary Loan Article Request"))
                    ServiceTiles(tile: ServiceTile(picture: "IntLibLoanBookReqPicture", title: "Interlibrary Loan Book Request"))
                }
            }
            
            Spacer()
            
                VStack {
                    HStack {
                        NavigationLink(destination: ContactUsView()) {
                            ServiceTiles(tile: ServiceTile(picture: "ContactUs", title: "Contact Us"))
                        }
                        HStack {
                            NavigationLink(destination: LibraryStaffView()) {
                                ServiceTiles(tile: ServiceTile(picture: "LibraryStaffPicture", title: "Library Staff"))
                            }
                        }
                        
                    }
                }
            
        }
        
        
    }
}

func libraryClosingText() -> String {
    let closingTime = Calendar.current.date(bySettingHour: 21, minute: 0, second: 0, of: currentTime) ?? Date()
            let now = currentTime // Use the updated current time
    
    // Format the closing time as a string
    let formatter = DateFormatter()
    formatter.timeStyle = .short
    let closingTimeString = formatter.string(from: closingTime)
    
    // Calculate the difference in minutes
    let difference = Calendar.current.dateComponents([.minute], from: now, to: closingTime).minute ?? 0
    
    if (difference < 0)
    {
        return "The Library is closed"
    }
    
   else
    {
       return "The Library closes at \(closingTimeString) today (In \(difference) Minutes)"
   }
    
}


    
    func calculateTimeRemaining() -> String {
        // Implementation of your time calculation logic
        // Placeholder example:
        let closingTime = Calendar.current.date(bySettingHour: 21, minute: 0, second: 0, of: Date())!
        let now = Date()
        let remaining = Calendar.current.dateComponents([.minute], from: now, to: closingTime).minute ?? 0

        if remaining <= 0 {
            return "Closed"
        } else {
            return "\(remaining) minutes"
        }


       }
    }

#Preview {
    HomeView()
}

Here's the other files that might help

    import Foundation
import ActivityKit

class LiveActivityManager {

@discardableResult
static func startActivity(timeRemaining: String) throws -> String {
    var activity: Activity<ClosingTimeAttributes>?
    let initialState = ClosingTimeAttributes.ContentState(timeRemaining: timeRemaining)
    
    do {
        activity = try Activity.request(attributes: ClosingTimeAttributes(), contentState: initialState, pushType: nil)
        guard let id = activity?.id else { throw LiveActivityErrorType.failedToGetID }
        return id // Ensure this returns a String representation of the ID
    } catch {
        throw error
    }
}

static func listAllAttributes() -> [[String:String]] {
    let sortedActivities = Activity<ClosingTimeAttributes>.activities.sorted { $0.id > $1.id }
    return sortedActivities.map { ["timeRemaining": $0.contentState.timeRemaining] }
}

static func endAllActivities() async {
    for activity in Activity<ClosingTimeAttributes>.activities {
        await activity.end(dismissalPolicy: .immediate)
    }
}

static func endActivity(_ id: String) async {
        // Assuming 'id' is a String that represents a UUID, we need to find the corresponding Activity
        // by matching its UUID string representation with 'id'
        await Activity<ClosingTimeAttributes>.activities.first { $0.id == id }?.end(dismissalPolicy: .immediate)
    }
    
    static func updateActivity(id: String, timeRemaining: String) async {
        // Here also, 'id' is a String. We match it against the uuidString representation of each Activity's UUID
        let updatedContentState = ClosingTimeAttributes.ContentState(timeRemaining: timeRemaining)
        let activity = Activity<ClosingTimeAttributes>.activities.first { $0.id == id }
        await activity?.update(using: updatedContentState)
    }

enum LiveActivityErrorType: Error {
    case failedToGetID
}

}

import Foundation
import ActivityKit

struct ClosingTimeAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        var timeRemaining: String
        
        }
    }

ClosingTimeBundle

import WidgetKit
import SwiftUI

@main
struct ClosingTimeBundle: WidgetBundle {
    var body: some Widget {
        ClosingTime()
    }
}

ClosingTime.swift

import WidgetKit
import SwiftUI
import Trexler_Library

struct ClosingTime: Widget {

var body: some WidgetConfiguration {
    ActivityConfiguration(for: ClosingTimeAttributes.self ) {context in
        
        VStack(alignment: .center) {
            VStack(alignment: .center) {
                HStack {
                    Image(systemName: "takeoutbag.and.cup.and.straw.fill")
                        .resizable().aspectRatio(contentMode: .fit)
                        .frame(width: 14, height: 14)
                        .foregroundColor(.yellow)
                    
                    Spacer()
                    
                    Text("~ \(context.state.timeRemaining)")
                        .font(.system(size: 14))
                        .bold()
                }
                .padding(.horizontal, 10)
                
                VStack {
                    HStack {
                        Image(systemName: "figure.outdoor.cycle")
                            .resizable().aspectRatio(contentMode: .fit)
                            .frame(width: 44, height: 44)
                            .foregroundColor(.yellow)
                        
                        VStack(spacing: 0) {
                            HStack {
                                Text("Your food is on delivery")
                                    .font(.system(size: 20))
                                    .bold()
                                
                                Spacer()
                            }
                        }
                    }
                    .padding(.horizontal, 30)
                }
            }
            
            HStack {
                VStack(alignment: .leading) {
                    Text("From")
                        .font(.system(size: 8))
                    Text(context.state.timeRemaining)
                        .font(.system(size: 14))
                        .bold()
                }
                
                Spacer()
                
                VStack(alignment: .trailing) {
                    Text("To")
                        .font(.system(size: 8))
                    Text(context.state.timeRemaining)
                        .font(.system(size: 14))
                        .bold()
                }
            }
            .frame(height: 20)
            .padding(.horizontal, 10)
            
            HStack {
                ProgressView(value: CGFloat((context.state.timeRemaining as NSString).floatValue), total: 100)
                    .tint(.yellow)
                    .background(.white)
            }
            .padding(.horizontal, 10)
            
        }
        .frame(height: 160)
        .background(.black)
        
       
        
    } dynamicIsland: { context in
        DynamicIsland {
            DynamicIslandExpandedRegion(.center) {
                VStack {
                    HStack {
                        Image(systemName: "takeoutbag.and.cup.and.straw.fill")
                            .resizable().aspectRatio(contentMode: .fit)
                            .frame(width: 14, height: 14)
                            .foregroundColor(.yellow)
                        Spacer()
                        Text("~ \(context.state.timeRemaining)")
                            .font(.system(size: 14))
                            .bold()
                    }
                    .padding(.horizontal, 10)
                    
                    VStack {
                        HStack {
                            Image(systemName: "figure.outdoor.cycle")
                                .resizable().aspectRatio(contentMode: .fit)
                                .frame(width: 44, height: 44)
                                .foregroundColor(.yellow)
                            
                            VStack(spacing: 0) {
                                HStack {
                                    Text("Your food is on delivery")
                                        .font(.system(size: 20))
                                        .bold()
                                    
                                    Spacer()
                                }
                                HStack {
                                    Button(action: {}, label: {
                                        HStack {
                                            Image(systemName: "phone.fill")
                                                .resizable().aspectRatio(contentMode: .fit)
                                                .frame(width: 14, height: 14)
                                                .foregroundColor(.white)
                                            
                                            Text("Call")
                                                .font(.system(size: 10))
                                                .foregroundStyle(.white)
                                        }
                                    })
                                    .buttonBorderShape(.capsule)
                                    Spacer()
                                }
                                
                            }
                        }.padding(.horizontal, 30)
                    }
                    
                }
            }
            DynamicIslandExpandedRegion(.bottom) {
                HStack {
                    VStack(alignment: .leading) {
                        Text("From")
                            .font(.system(size: 8))
                        Text(context.state.timeRemaining)
                            .font(.system(size: 14))
                            .bold()
                    }
                    
                    Spacer()
                    
                    VStack(alignment: .leading) {
                        Text("To")
                            .font(.system(size: 8))
                        Text(context.state.timeRemaining)
                            .font(.system(size: 14))
                            .bold()
                    }
                }
                .frame(height: 20)
                .padding(.horizontal, 10)
            }
        } compactLeading: {
            Image(systemName: "clock")
                .resizable().aspectRatio(contentMode: .fit)
                .frame(width: 14, height: 14)
                .foregroundColor(.yellow)
        } compactTrailing: {
            Text(context.state.timeRemaining)
        } minimal: {
            Image(systemName: "takeoutbag.and.cup.and.straw.fill")
                .resizable().aspectRatio(contentMode: .fit)
                .frame(width: 14, height: 14)
                .foregroundColor(.yellow)
        }
    }
        
    }
    
}
0

There are 0 best solutions below