Post

Replies

Boosts

Views

Activity

Reply to Can Widget send a network request when phone is locked?
I'm answering this way late, but what about a BackgroundTask? These will definitely run even if the device is locked and turned off, as long as the app is running. The only bad thing is you don't get to choose when it runs; the device decides when to run. However, they seem to run pretty quickly after locking the device, from my experience, and you can have the task schedule another task when it's done, so they can keep being scheduled repeatedly. https://developer.apple.com/documentation/backgroundtasks
Jan ’22
Reply to TLS authentication with *.pfx certificate on iOS from MDM
Wow, this is awesome info Quinn, thanks for explaining all this. One other question: When I do a manual install of a *.pfx digital identity by dragging it onto an iOS Simulator like I did in my testing, and it appears under that "Configuration Profile" section in Settings, I'm just seeing the profile, right? But behind the scenes it has also installed part of its payload into the separate trust store subsystem? When I click "More Details", it takes me to a "Certificate" section, and I can see a Certificate name, and when I click that, it takes me to a long detail section, where I can see the issuer name, the public key info, the certificate authority, the signature, etc. Is this essentially showing me part of that trust store subsystem? Or is there another place in iOS where you can see the entire contents of that trust store subsystem (ie, does iOS have an equivalent of the MacOS Keychain, which shows you everything installed?). Oddity about iOS: If these digital identities are NOT accessible from the app, why does iOS allow me to install it at all? Won't they just sit there, completely walled-off and useless?
Jun ’22
Reply to SwiftUI and "Simultaneous access" error
Hi Claude, thank you for responding on this. When I use the print statement, it prints isViewingSideBySide true There's no problem reading its value; it's just changing it that crashes. The var mainScreenRecs is defined as an ObservableObject, class MainScreenRecs: ObservableObject { ...     @Published var isViewingSideBySides = false } and is instantiated in the App struct as a StateObject, struct EtimsEcpApp: App { ...     @StateObject var myRecs = MainScreenRecs(recs: [], ... isViewingSideBySide: false } and is passed into MainListView, var body: some Scene {         WindowGroup {             MainListView(myRecs: self.myRecs) ... } } where it's defined as an ObservedObject, and then to the child view PDFSidebar also as an ObservedObject: struct MainListView: View {     @ObservedObject var myRecs: MainScreenRecs ...     var body: some View { ...                 PDFSidebar(mainScreenRecs: myRecs) In the PDFSide, it's an ObservedObject: struct PDFSidebar: View {     @ObservedObject var mainScreenRecs: MainScreenRecs That's where the "Close Side by Side" button is located. I also noticed that the crash only occurs if you've tapped the face of the PDFKit viewer. When you tap the face of the PDFKit viewer, you get this blast of messages: objc[40678]: Class _PathPoint is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore (0x11d77b658) and /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/TextInputUI.framework/TextInputUI (0x13fa5d690). One of the two will be used. Which one is undefined.
Jul ’22
Reply to SwiftUI and "Simultaneous access" error
I stripped down the views controlled by the isViewingSideBySide variable to just "Hello World", and don't receive the error, so I'm going to build them back piece by piece until I hit on what's causing the "simultaneous access" error. @Claude31, thanks for the time and effort up to this point though.
Jul ’22
Reply to SwiftUI and "Simultaneous access" error
Finally solved this. The problem was that I wanted to maintain the state of the PDFKit views when switching between them (like what page you're on, how much you're zoomed in on a page, etc), so I maintain a copy of the PDFView objects after instantiating them, but I wasn't handling the makeUIView and updateUIView methods properly, which are called constantly in SwiftUI when switching between the different PDFViews, even though I wasn't unloading the views. There's not a lot of documentation about using PDFKit and SwiftUI, especially the way we're doing it with an app that needs to open multiple PDFs and display them in tabs, and even display two of them side-by-side at the same time. Here is what my core SwiftUI wrapper around PDFKit now looks like: import PDFKit import SwiftUI struct PDFViewSwiftUIWrapper: UIViewRepresentable {     var myViewerModel: PDFViewerModel     func makeUIView(context: Context) -> PDFView {         return myViewerModel.myPDFView     }     func updateUIView(_ pdfView: PDFView, context: Context) {         pdfView.document = myViewerModel.myPDFView.document     } } It's super-basic, but both functions need to do something; I thought "updateUIView" would only be called if you were displaying a different PDF in the same viewer, but it gets called every time the view displays. The PDFViewerModel is the class that I instantiate and hold on to. I have one of these for each PDF tab that is opened in the app. By keeping a copy of this, which has the PDFView in it, I can maintain the state of PDFView, like the zoom level, the page #, etc: // I have to set this as Indentifiable so I can use it with ForEach class PDFViewerModel: ObservableObject, Identifiable {     var myPDFView = PDFView() // There are other properties like these so we can have additional state for the viewer, like a word search textbox. This isn't part of PDFView; you have to add these UI features.     var showBookmarkPopover = false     var showSearchToolbar = false ... } When you click to open another PDF in a new tab, it instantiates it and adds it to the array like this: let pdfViewerModel = PDFViewerModel() if let unwrappedPdfDoc = PDFDocument(url: getMyURL()) {       pdfViewerModel.myPDFView.document = unwrappedPdfDoc } currentTabs.append(pdfViewerModel) There's a SwiftUI view that displays the PDFViewSwiftUIWrapper and some other helper controls, like the search toolbar, and each of these is displayed like this: ForEach(currentTabs) { pdfViewerModel in     PDFViewer(pdfViewerModel: pdfViewerModel) } This problem was a hybrid of the way SwiftUI gets called repeatedly, which I didn't realize, even if the state hadn't necessarily changed, along with the correct way to integrate PDFKit into SwiftUI. Hope this helps anyone with a similar issue!
Jul ’22
Reply to SwiftUI hidesBottomBarWhenPushed equivalent?
What if you do it like this? So the TabView is embedded in a specific set of pages, and when you navigate to the details page, it's not part of the TabPage hierarchy? import SwiftUI struct ContentView: View { var body: some View { NavigationView { HomeViewWithTabs() } } } struct HomeViewWithTabs: View { var body: some View { TabView { TabPage1() .tabItem { Image(systemName: "house.fill") Text("Home") } TabPage2() .tabItem { Image(systemName: "bookmark.circle.fill") Text("Bookmark") } } } } struct TabPage1: View { var body: some View { VStack { Text("I am tab page 1") .padding() .background(.red) NavigationLink { DetailsView() } label: { Text("Click me to go to the details view") } } } } struct TabPage2: View { var body: some View { Text("I am tab page 2") .padding() .background(.green) } } struct DetailsView: View { var body: some View { Text("I am the details view") } }
Jul ’22
Reply to XCUIElementQuery in SwiftUI testing returns inconsistent count
This answer https://stackoverflow.com/a/37320452 pointed me in the right direction. The fix is to put a pause in the form of sleep(1), to give the query time to do its fetch, I assume. let pred = NSPredicate(format: "identifier == 'detailViewTable'") let detailViewTable = app.descendants(matching: .any).matching(pred).firstMatch let arrOfTexts = detailViewTable.staticTexts sleep(1) // <-- Add this let ct = arrOfTexts.count print("Count is: \(ct)") // Now prints 21 print("Count is now: \(detailViewTable.staticTexts.count)") // Also prints 21
Aug ’22
Reply to Problem with PFX Certificate and Background Task
If the item has already been added to the Keychain, it won't update unless you explicitly delete it with SecItemDelete, or update it with SecItemUpdate. Once I deleted it and re-added it, it does work using kSecAttrAccessibleAfterFirstUnlock. Still curious if this could be done without the Keychain, but I'm guessing that's you only choice, or I would've come across more code examples showing alternate methods.
Sep ’22
Reply to Why @Bindable and not @Binding in SwiftUI for iOS 17
Hi, thanks so much for responding. For @State, you said, Use to create a single source of truth for a given value type in a view. Shouldn't be used for reference types as SwiftUI won't update the view when one of its properties changes. However, I don't think this is right (it was pre-iOS17, but not now). In the video at 4:50, he shows Donut being used with @State: and at 6:19 he shows that Donut is a class and not a struct, so it is a reference type: This makes sense to me, because from everything I've read, they've consolidated the pre-iOS17 @State (for value types) and @StateObject (for reference types) into @State (for both value types AND reference types). As Natascha says in her article, Before the Observation framework, we used @State for value types and @StateObject for reference types to let SwiftUI update views whenever changes occured. With Observation, both types are covered by @State: In the book "Working With Data" by Mark Moeykens of Big Mountain Studio, he has a great illustration of the pre-iOS 17 usage: and based on Natascha's article, the new usage will be like this: I'm curious why They merged @State and @StateObject into just @State for both value and ref types, but didn't do the same for @Binding and @ObservedObject into just @Binding, but rather kept @Binding as-is, and just changed the name of @ObservedObject into @Bindable (as Natascha says, "Before the Observation framework, we used @Binding for value types and @ObservedObject for reference types to create two-way bindings. With Observation, we use @Binding for value types and @Bindable for reference types"). @Binding actually seems to work for a ref type.
Aug ’23