I have an iOS/iPadOS app. When I run the app on Mac as a Designed for iPad app, Save button on the Share Sheet crashes the app.
I want to share a view with ImageRenderer, but here's an even easier example where I am trying to share an SF Symbol as an image.
ShareLink(item: Image(systemName: "swift"), preview: SharePreview(Text("PNG"), image: Image(systemName: "swift")))
Share button works. It opens Share Sheet. "Add to Photos" works. "Copy" works. I can paste the image file in Finder after I press "Copy". But when I press the "Save" button, my app crashes with the error:
Thread 1: "-[NSItemProvider pathExtension]: unrecognized selector sent to instance 0x600001c1e290"
How to fix this error? How to make saving the image work? Maybe I need additional permissions in plist? I already have "Privacy - Photo Library Additions Usage Description" and everything on iOS and iPadOS works without a problem.
Post
Replies
Boosts
Views
Activity
👋 Hey, folks.
Does Apple convert app screenshots uploaded to App Store Connect before displaying them on the App Store?
In other words, is it better to upload PNG files for better quality or JPG files for lower file size and faster loading?
I want to release my first iOS app on App Store. I would like to make it iOS only. Without an option to download and run on iPad and Mac.
However, TestFlight shows me this app on both iPad and Mac.
Why can I test my iOS app on iPad when I specifically disabled iPad in Target’s Deployment Info? How to disable it? How to prevent the app from distributing to iPad and Mac?
Deployment info is set to iPhone only. On App Store Connect I didn't add macOS app. And yet, it's still available in TestFlight and under compatibility it says: iPhone, iPad, macOS.
I'm trying to make a list of Core Data items in SwiftUI where adding new item will also trigger scroll to last item.
Here is a code I have. It's based on sample Core Data app in Xcode. One Entity: Item with one attribute: timestamp.
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
var body: some View {
NavigationView {
ScrollViewReader { proxy in
ScrollView {
ForEach(items, id: \.self) { item in
Text("Some item")
.padding()
.id(item.objectID)
}
.onDelete(perform: deleteItems)
}
.onChange(of: items.count) { _ in
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
proxy.scrollTo(items.last?.objectID)
}
// }
}
.toolbar {
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
}
Text("Select an item")
}
}
private func addItem() {
withAnimation {
let newItem = Item(context: viewContext)
newItem.timestamp = Date()
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
It works, but I'm getting errors like this in Xcode:
2022-02-06 16:28:47.280984+0700 scroll[901:2894134] [error]
precondition failure: invalid graph update (access from multiple
threads?)
How to fix this? My guess is that it's something to do with concurrency. When new item is created it gets new id. Number of item changes. Core Data saves data. UI scrolls with animation. But maybe when scroll is triggered, swift is still not sure which item is last on the list?
So, things I've tried:
If you uncomment
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
And closing bracket as well - I am not getting an error when I'm adding one item at a time. But if I tap + few times, I'm getting errors again.
Another surprising thing is that if I change ScrollView to List, I am not getting errors at all. Even without DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
I would like to use Sign In with Apple JS on my website to show some pages or content only to predefined user. This is an example logic I would like to achieve:
if userID or userEmail == "someValue" {
// show page or content
}
In particular, I would like to show an admin panel only to users with particular username or email address or some ID or whatever.
I don't want to allow signing up with SIWA for anyone. And just use SIWA JS to allow a safe way of signing in.
Is it possible with Sign In with Apple JS?
P.s. Technology I would like to use on my website: HTML, CSS, PHP, JS.
I have added CloudKit support to my iOS app and after more than 1 hour nothing happened.
After few hours I got it to the point that:
single records are synced from iPad to iPhone. But still no sync from iPhone to iPad.
In this article from Apple - https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/syncing_a_core_data_store_with_cloudkit it says that "Generally, you can expect data to synchronize a local change within about a minute of the change."
More details on what I have done so far:
I have tested CloudKit first with my app's DEV version deployed directly to iPhone and iPad. Syncing started after approximately 20-30 minutes, I think.
After this I have added Signing & Capabilities to my main target. I have added the same as for DEV target: iCloud (CloudKit), Background Modes (Remote notifications).
After deploying with TestFlight and installing my app on iPhone and iPad, syncing hasn't started after more than 1 hour.
To clarify, I am using CloudKit with CoreData. This app that I am testing with TestFlight has some data already. But we are talking about few KB of data to be synced, not even MB.
I have also deployed the Development Schema to Production using instructions from this link: - https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitQuickStart/DeployingYourCloudKitApp/DeployingYourCloudKitApp.html
In CloudKit Dashboard, click "Deploy to Production…” button.
Review the changes that are going to be deployed.
Click “Deploy Changes.”
Is it normal that it takes long time for first iCloud sync? Will it work better later on? What am I missing? Why it didn't start to sync yet? Should I do something more? In code or in CloudKit Dashboard?
I have 2 TextFields:
__ x2 __
I want to perform simple calculations: string1 x 2 = string2. I am using .onChange modifier, so if you type first number it is multiplied by 2 and result is printed in second TextField. You can go the other way around and type string2 and it will be divided by 2 and result will be printed in the first TextField.
Now because both TextFields have .onChange, it gets triggered few times (3 in this case). After changing string1, string2 gets updated. And as it changed, .onChange of string2 is triggered and later the same with .onChange of string1.
Please run this example code and check what gets printed in console:
import SwiftUI
struct ContentView: View {
@State private var string1: String = ""
@State private var int1: Int = 0
@State private var string2: String = ""
@State private var int2: Int = 0
let multiplier: Int = 2
var body: some View {
VStack {
HStack {
TextField("0", text: $string1)
.keyboardType(.decimalPad)
.onChange(of: string1, perform: { value in
string1 = value
int1 = Int(string1) ?? 0
int2 = int1 * multiplier
string2 = "\(int2)"
print("int1: \(int1)")
})
}
.multilineTextAlignment(.trailing)
.font(.largeTitle)
.background(Color(UIColor.systemGray5))
HStack {
Spacer()
Text("x2")
}
HStack {
TextField("0", text: $string2)
.keyboardType(.decimalPad)
.onChange(of: string2, perform: { value in
string2 = value
int2 = Int(string2) ?? 0
int1 = int2 / multiplier
string1 = ("\(int1)")
print("int2: \(int2)")
})
}
.multilineTextAlignment(.trailing)
.font(.largeTitle)
.background(Color(UIColor.systemGray5))
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Question:
How to make .onChange conditional so it runs only once? To be precise, I want to execute .onChange on first input ONLY when I edit first input. And execute .onChange on second input ONLY when I edit second input.
Probably it will be easy with .onFocus in iOS 15. But how to do it in iOS 14?
I have created an iCloud container for my iOS app in Signing & Capabilities section of TARGETS named iCloud.myApp
I have many problems with iCloud and I found in one tutorial that:
The app’s bundle ID and iCloud containers must match and they must exist in the developer account. For example, if the bundle identifier is com.myDomain.myApp, then the iCloud container name should be iCloud. plus the bundle bundle id: iCloud.com.myDomain.myApp.
So the question is how and where to change it from iCloud.myApp to iCloud.com.myDomain.myApp?
Containers in Signing & Capabilities are not editable. I cannot find it in CloudKitDashboard as well. Or should I create a new container?