Has anyone tried to display a contact with the CNContactViewController making one of the email addresses highlighted? I tried it, but if I use the highlightPropertyWithKey method, the resulting controller is blank and the following message is logged:[CNUI ERROR] error calling service - Couldn’t communicate with a helper application.I also tried using the deprecated API (ABPersonViewController), and the result is exactly the same. It works fine on iOS8 though.Here's a sample code: func openAppleSeed(highlight:Bool) {
let store = CNContactStore()
let request = CNContactFetchRequest(keysToFetch: [CNContactEmailAddressesKey]);
do {
try store.enumerateContactsWithFetchRequest(request, usingBlock: {
(contact:CNContact, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
for address in contact.emailAddresses
{
if address.value as! String == "John-Appleseed@mac.com" {
do {
let fullContact = try store.unifiedContactWithIdentifier(contact.identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys()])
let vc = CNContactViewController(forContact: fullContact)
vc.contactStore = store
if highlight {
vc.highlightPropertyWithKey(CNContactEmailAddressesKey, identifier: address.identifier)
}
self.navigationController?.pushViewController(vc, animated: true)
return
}
catch {
print("CATCHING (B)")
}
return;
}
}
})
}
catch {
print("CATCHING (A)")
}
}Calling this function openAppleseed(highlight:false) works fine, but openAppleseed(highlight:true) generates the blank view controller and the log message mentioned aboved.I tested it with the latest beta (5), and both simulator and device. Same result. I am submitting a bug report now, but I was curious if anyone had the same issue. Any workarounds?Cheers.
Post
Replies
Boosts
Views
Activity
I have created a very simple example of how a UIViewController represented by UIViewControllerRepresentable is never deallocated.struct ContentView : View {
@State private var showRepView = true
var body: some View {
VStack {
Text("Square").font(.largeTitle).tapAction {
self.showRepView.toggle()
}
if showRepView {
SomeRepView().frame(width: 100, height: 200)
}
}
}
}The representation implementation follows:struct SomeRepView: View {
var body: some View {
RepViewController()
}
}
struct RepViewController: UIViewControllerRepresentable
{
func makeUIViewController(context: Context) -> SomeCustomeUIViewController {
let vc = SomeCustomeUIViewController()
print("INIT \(vc)")
return vc
}
func updateUIViewController(_ uiViewController: SomeCustomeUIViewController, context: Context) {
}
static func dismantleUIViewController(_ uiViewController: SomeCustomeUIViewController, coordinator: Self.Coordinator) {
print("DISMANTLE")
}
}
class SomeCustomeUIViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.green
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("viewWillDissapear \(self)")
}
deinit {
print("DEINIT \(self)")
}
}By tapping on the "Square" button, SomeRepView is added and removed alternatively. However, the related UIViewController is never released.That can be seen by the logged messages and I also confirmed with Instruments.Note that SomeRepView is released properly. It is only the corresponding view controller what remains allocated.Also note that the UIViewController.viewWillDissappear is called and also the UIViewControllerRepresentable.dismantleUIViewControllerThis is a typical output when pressing the Square button repeatedly.INIT <SomeCustomeUIViewController: 0x100b1af70>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100b1af70>
INIT <SomeCustomeUIViewController: 0x100a0a8c0>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100a0a8c0>
INIT <SomeCustomeUIViewController: 0x100b23690>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100b23690>As shown, DEINIT is never printed.Running with iOS13, beta 2, iPad 6th Gen and on the simulator. I also tried triggered a Simulate Memory Warning. But no effect. The controllers persist in memory.My question is... is it a bug? Or am I doing something wrong?
I was running iPadOS 16.0 beta 3 with developer mode enabled and all was good. For reasons that are not important to this post, I had to do an "Erase All Contents and Settings". After the OS reinstall, I signed-in with the same Apple Id as before, I re-downloaded the beta profile from Apple, and went to enable "developer mode" (which requires a reboot). However, upon restart, developer mode remains disabled. I tried several times, but developer mode just won't turn on.
Now I'm left with no device to test iOS16 apps :-(
Restoring a NavigationStack path (NavigationPath) from a codable representation, crashes the app with the following error:
Failed to decode item in navigation path at index 0. Perhaps the navigationDestination declarations have changed since the path was encoded?
Fatal error: throw through?
Note that the error is thrown when the view appears, not when the NavigationPath(representation) is initialized.
In this example, navigation declarations have not changed and restoration should succeed. However, even there was an error restoring the path, this should not be a fatal error. It should be handled gracefully. Consider a new app version being distributed where the destinations did changed. The stack restoration should fail and navigate to the root, but not crash.
Problem occurs both in iOS 16 beta 3 and macOS 13 beta 3.
struct Movie: Identifiable, Hashable, Codable {
let id: Int
let name: String
let year: Int
}
struct TVShow: Identifiable, Hashable, Codable {
let id: Int
let name: String
let episodes: Int
}
class Model: ObservableObject {
let movies = [
Movie(id: 1, name: "Blade Runner", year: 1982),
Movie(id: 2, name: "Back to the Future", year: 1985),
Movie(id: 3, name: "Mission Impossible", year: 1996),
]
let shows = [
TVShow(id: 1, name: "Cheers", episodes: 275),
TVShow(id: 2, name: "Taxi", episodes: 114)
]
@Published var path: NavigationPath
init() {
if let data = UserDefaults.standard.object(forKey: "path") as? Data {
do {
let representation = try JSONDecoder().decode(NavigationPath.CodableRepresentation.self, from: data)
self.path = NavigationPath(representation)
} catch {
print("Unable to decode path \(error)")
self.path = NavigationPath()
}
} else {
self.path = NavigationPath()
}
}
func save() {
guard let representation = path.codable else { return }
do {
let encoder = JSONEncoder()
let data = try encoder.encode(representation)
UserDefaults.standard.set(data, forKey: "path")
} catch {
print("Unable to encode path \(error)")
}
}
}
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
@StateObject var model = Model()
var body: some View {
NavigationStack(path: $model.path)
{
List {
Section("Movies") {
ForEach(model.movies) { movie in
NavigationLink(movie.name, value: movie)
}
}
Section("TV Shows") {
ForEach(model.shows) { show in
NavigationLink(show.name, value: show)
}
}
}
.navigationDestination(for: Movie.self, destination: { MovieView(movie: $0) })
.navigationDestination(for: TVShow.self, destination: { TVShowView(show: $0) })
}
.onChange(of: scenePhase) { phase in
if phase == .background {
model.save()
}
}
}
}
struct MovieView: View {
let movie: Movie
var body: some View {
Form {
LabeledContent("Title", value: movie.name)
LabeledContent("Year" , value: "\(movie.year)")
}
}
}
struct TVShowView: View {
let show: TVShow
var body: some View {
Form {
LabeledContent("Title", value: show.name)
LabeledContent("Episodes" , value: "\(show.episodes)")
}
}
}