简体   繁体   English

根据 SwiftUI 的权限更改视图?

[英]Change view based on permissions with SwiftUI?

I have coded an application that needs the permissions of the photo library.我编写了一个需要照片库权限的应用程序。 The worry is that it needs it as soon as the application is launched so it must check at the start of the application the permission granted and if it is not determined, ask for it, wait for the result and change the view again, I've been breaking my head for three days?担心的是它在应用程序启动后立即需要它,因此它必须在应用程序启动时检查授予的权限,如果不确定,则请求它,等待结果并再次更改视图,我'我的头已经断了三天了? but I can't do it: Can you help me?但我做不到:你能帮帮我吗? Here is my code:这是我的代码:

Content view:内容视图:

    struct ContentView: View {
    var auth = false
    @State var limitedAlert = false
    @State var statusPhoto = 0
    @State var AuthPictStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)
    var body: some View {
        VStack{}
            .task{
                while true {
                    AuthPictStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)
                }
            }
            if AuthPictStatus == .authorized {
                CardView(canExecute: true)
            }
            if AuthPictStatus == .denied {
                PhotoLybrairyDenied()
            }
            if AuthPictStatus == .limited {
                CardView(canExecute: true)
                    .onAppear{limitedAlert = true}
                    .alert(isPresented: $limitedAlert) {
                        Alert(
                            title: Text("L'accès au photos est limitées !"),
                            message: Text("Votre autorisations ne nous permets d'accèder a seulement certaines photos ! De se fait, nous ne pouvons pas trier l'intégralité de vos photos !"),
                            primaryButton: .destructive(Text("Continuer malgré tout"), action: {
                                
                            }),
                            secondaryButton: .default(Text("Modifier l'autorisation"), action: { // 1
                                guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                                            return
                                        }

                                        if UIApplication.shared.canOpenURL(settingsUrl) {
                                            UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                                                print("Settings opened: \(success)") // Prints true
                                            })
                                        }
                                    
                            })
                        )
                    }
                }
            if AuthPictStatus == .notDetermined {
                CardView(canExecute: false)
                    .blur(radius: 5)
                    .disabled(true)
            }
        
        
    }
}

PhotoDeleteApp:照片删除应用程序:

//
//  PhotoDeleteApp.swift
//  PhotoDelete
//
//  Created by Rémy on 09/04/2022.
//

import SwiftUI
import Photos

@main
struct PhotoDeleteApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear{
                    PHPhotoLibrary.requestAuthorization({status in })
                }
        }
    }
}
//
//  PhotoDeleteApp.swift
//  PhotoDelete
//
//  Created by Rémy on 09/04/2022.
//

import SwiftUI
import Photos

@main
struct PhotoDeleteApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear{
                    PHPhotoLibrary.requestAuthorization({status in })
                }
        }
    }
}

I dealt with similar headaches related to photo permissions (I'm on SwiftUI and iOS 14).我处理过与照片权限相关的类似问题(我在 SwiftUI 和 iOS 14)。 I did some troubleshooting and found that using a SwiftUIViewDelegate to implement custom authorization status wasnt working as expected.我做了一些故障排除,发现使用SwiftUIViewDelegate实现自定义授权状态没有按预期工作。 I did a test and selected "only selected photos" (which should make the authorization status .limited ).我做了一个测试并选择了“仅选定的照片”(这应该使授权状态为.limited )。 Except the authorization status wasn't limited, but .authorized , and .denied only when I denied access entirely.除了授权状态不受限制,但.authorized.denied仅当我完全拒绝访问时。

So in my SwiftUI app, I gave up trying to be fancy and used the package Permissions SwiftUI. It provides some documentation on how to customize the message, but it handles the permissions using a sheet making the implementation carefree (It does not address .limited case either or the bug I described with the user selecting limited being actually full access).所以在我的 SwiftUI 应用程序中,我放弃了花哨的尝试并使用了 package 权限 SwiftUI。它提供了一些关于如何自定义消息的文档,但它使用一个表来处理权限,使实现无忧无虑(它没有解决.limited情况或者我描述的用户选择有限实际上是完全访问的错误)。

My implementation looks like this, and is in my entry point @main , under the first View HomeTabView(homeViewModel: homeViewModel) inside the WindowGroup { }我的实现看起来像这样,在我的入口点@main中,在WindowGroup { }内的第一个 View HomeTabView(homeViewModel: homeViewModel)

.JMModal(showModal: $homeViewModel.showingPermissionsSelector, for: [.photo], autoDismiss: true, autoCheckAuthorization: false, restrictDismissal: false)
            .changeHeaderTo("App Permissions")
            .changeHeaderDescriptionTo("Export and Import of images requires photos access.")
            .changeBottomDescriptionTo("Allowing the app to import photos provides the app access to airdropped and saved user photos.")

I suggest you try it out and see if it's good enough for your purposes.我建议您尝试一下,看看它是否足以满足您的目的。 To include the Permissions SwiftUI package in your project, go to your Project in the left panel, select "Project", go to "Package Dependencies" on the top bar, press the + button, and search for Permissions SwiftUI, there will be many options but only add PermissionsSwiftUIPhoto .要在您的项目中包含权限 SwiftUI package,在左侧面板中为您的项目添加权限 go,在顶部栏中添加 select“项目”,go 到“包依赖项”,按 + 按钮,然后搜索权限 89486825选项,但只添加PermissionsSwiftUIPhoto If you need other permissions, there are plenty to choose from.如果您需要其他权限,有很多可供选择。

I have the permissions bound to a "import photos" button (in a subview) hence HomeTabViewModel belongs to parent我有权限绑定到“导入照片”按钮(在子视图中)因此 HomeTabViewModel 属于parent

Button(action: {
            let authorization = PHPhotoLibrary.authorizationStatus()
            print("switching on image authorization status: \(authorization)")
            switch authorization {
            case .notDetermined:
                parent.homeVM.showingPermissionsSelector = true
            case .restricted:
                parent.homeVM.showingPermissionsSelector = true
            case .denied:
                parent.homeVM.showingPermissionsSelector = true
            case .authorized:
                parent.homeVM.showingImagePicker = true
            case .limited:
                parent.homeVM.showingImagePicker = true // I've never reached this case (bug?)
            @unknown default:
                print("unhandled authorization status")
                break
            }

my homeViewModel (simplified for example)我的 homeViewModel(例如简化版)

import SwiftUI

final class HomeTabViewModel: ObservableObject {
    @Published var showingPermissionsSelector = false
    @Published var showingImagePicker         = false
   // @Published var showingLimitedSelector = false // Thought I would need this but I dont because there is no differentiation between .authorized and .denied from my testing
}

but you could have your app do an .onAppear { // check auth status and change $homeViewModel.showingPermissionsSelector based on your code's logic}但您可以让您的应用执行.onAppear { // check auth status and change $homeViewModel.showingPermissionsSelector based on your code's logic}

I dealt with the same problem you are having Rémy, and on one hand I'm glad I dont have to differentiate between .limited and .authorized since it makes it easier for us, but also it's a bit spooky because it means photo authorization is not quite working as expected on iOS...我处理了与 Rémy 相同的问题,一方面我很高兴我不必区分.limited.authorized因为它让我们更容易,但它也有点怪异因为它意味着照片授权是在 iOS 上没有按预期工作......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM