UICloudSharingController 不显示/不与 CloudKit 应用程序一起使用
Posted
技术标签:
【中文标题】UICloudSharingController 不显示/不与 CloudKit 应用程序一起使用【英文标题】:UICloudSharingController Does not Display/Work with CloudKit App 【发布时间】:2021-11-07 00:30:51 【问题描述】:我一直在努力让应用程序与 CloudKit 和记录共享一起工作。我有 为一个用户创建了几个在设备之间同步 Core Data 记录的应用程序。我没有 能够让 UICloudSharingController 用于共享记录。我可以显示 共享视图控制器,但点击邮件或消息显示键盘但没有 地址字段,无法关闭视图。我对此感到非常沮丧,以至于我 决定从基础开始尝试 Apple“共享”示例应用程序。然而 示例应用也不适合我。
以下是示例应用的链接: https://github.com/apple/cloudkit-sample-sharing/tree/swift-concurrency
下面的代码几乎直接来自示例应用程序。
这是 ContentView 文件:
import SwiftUI
import CloudKit
struct ContentView: View
@EnvironmentObject private var vm: ViewModel
@State private var isAddingContact = false
@State private var isSharing = false
@State private var isProcessingShare = false
@State private var showShareView = false
@State private var showIntermediateView = false
@State private var activeShare: CKShare?
@State private var activeContainer: CKContainer?
var body: some View
NavigationView
contentView
.navigationTitle("Contacts")
.toolbar
ToolbarItem(placement: .navigationBarLeading)
Button Task.init try await vm.refresh() label: Image(systemName: "arrow.clockwise")
ToolbarItem(placement: .navigationBarLeading)
progressView
ToolbarItem(placement: .navigationBarTrailing)
Button(action: isAddingContact = true ) Image(systemName: "plus")
.onAppear
Task.init
try await vm.initialize()
try await vm.refresh()
.sheet(isPresented: $isAddingContact, content:
AddContactView(onAdd: addContact, onCancel: isAddingContact = false )
)
/// This progress view will display when either the ViewModel is loading, or a share is processing.
var progressView: some View
let showProgress: Bool =
if case .loading = vm.state
return true
else if isProcessingShare
return true
return false
()
return Group
if showProgress
ProgressView()
/// Dynamic view built from ViewModel state.
private var contentView: some View
Group
switch vm.state
case let .loaded(privateContacts, sharedContacts):
List
Section(header: Text("Private"))
ForEach(privateContacts) contactRowView(for: $0)
Section(header: Text("Shared"))
ForEach(sharedContacts) contactRowView(for: $0, shareable: false)
.listStyle(GroupedListStyle())
case .error(let error):
VStack
Text("An error occurred: \(error.localizedDescription)").padding()
Spacer()
case .loading:
VStack EmptyView()
/// Builds a `CloudSharingView` with state after processing a share.
private func shareView() -> CloudSharingView?
guard let share = activeShare, let container = activeContainer else
return nil
return CloudSharingView(container: container, share: share)
/// Builds a Contact row view for display contact information in a List.
private func contactRowView(for contact: Contact, shareable: Bool = true) -> some View
HStack
VStack(alignment: .leading)
Text(contact.name)
Text(contact.phoneNumber)
.textContentType(.telephoneNumber)
.font(.footnote)
if shareable
Spacer()
Button(action: Task.init try? await shareContact(contact)
, label: Image(systemName: "square.and.arrow.up") ).buttonStyle(BorderlessButtonStyle())
.sheet(isPresented: $isSharing, content: shareView() )
//if sharable
//h
//contact row view
// MARK: - Actions
private func addContact(name: String, phoneNumber: String) async throws
try await vm.addContact(name: name, phoneNumber: phoneNumber)
try await vm.refresh()
isAddingContact = false
private func shareContact(_ contact: Contact) async throws
isProcessingShare = true
do
let (share, container) = try await vm.createShare(contact: contact)
isProcessingShare = false
activeShare = share
activeContainer = container
isSharing = true
catch
debugPrint("Error sharing contact record: \(error)")
以及共享视图的 UIViewControllerRepresentable 文件:
import Foundation
import SwiftUI
import UIKit
import CloudKit
/// This struct wraps a `UIImagePickerController` for use in SwiftUI.
struct CloudSharingView: UIViewControllerRepresentable
@Environment(\.presentationMode) var presentationMode
let container: CKContainer
let share: CKShare
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context)
func makeUIViewController(context: Context) -> some UIViewController
let sharingController = UICloudSharingController(share: share, container: container)
sharingController.availablePermissions = [.allowReadWrite, .allowPrivate]
sharingController.delegate = context.coordinator
return sharingController
func makeCoordinator() -> CloudSharingView.Coordinator
Coordinator()
final class Coordinator: NSObject, UICloudSharingControllerDelegate
func cloudSharingController(_ csc: UICloudSharingController, failedToSaveShareWithError error: Error)
debugPrint("Error saving share: \(error)")
func itemTitle(for csc: UICloudSharingController) -> String?
"Sharing Example"
这是点击分享记录时显示的屏幕。这一切看起来都符合预期:
这是点击消息后的屏幕(邮件的结果相同)。我没有看到任何影响第二个屏幕演示的方法 - 可表示的视图控制器似乎不适用于此版本的 Xcode:
任何指导将不胜感激。 Xcode 13.1、ios 15 和我在 macOS Monterrey 上。
【问题讨论】:
您好,您解决了这个问题吗? 很遗憾,没有。我把这个项目搁置一旁,直到找到解决办法。 【参考方案1】:我遇到了同样的问题,并通过更改 CloudSharingView.swift 中的 makeUIViewController() 来解决它:
func makeUIViewController(context: Context) -> some UIViewController
share[CKShare.SystemFieldKey.title] = "Boom"
let sharingController = UICloudSharingController(share: share, container: container)
sharingController.availablePermissions = [.allowReadWrite, .allowPrivate]
sharingController.delegate = context.coordinator
-->>> sharingController.modalPresentationStyle = .none
return sharingController
似乎有些有价值的工作,有些则不然。不知道为什么。
【讨论】:
哇。难以置信。是的,确实,禁用模态演示的行对我有用。谢谢。以上是关于UICloudSharingController 不显示/不与 CloudKit 应用程序一起使用的主要内容,如果未能解决你的问题,请参考以下文章
UICloudSharingController 在 Xcode 11 中显示无限活动指示