Posts

Post marked as solved
1 Replies
497 Views
I am testing an in-app purchase in my app. The app has a multiplatform target with Mac (native, not Catalyst) and iPad destinations. I created a local StoreKit configuration file in Xcode and added an IAP to it. I edited the Xcode scheme to use my local config file. I have the following code to fetch the IAP: @Published private(set) var products: [Product] @MainActor func fetchProducts() async { let productIdentifiers = ["com.pro_version"] do { products = try await Product.products(for: productIdentifiers) } catch { print("Failed product request from the App Store server: \(error)") } } When I call this function, the products array is always empty on Mac but is not empty on iOS. I checked that the product ID for the product in the config file matches the value of the productIdentifiers constant in the code. What am I missing that is preventing me from fetching the products from my local StoreKit config file on Mac?
Posted
by szymczyk.
Last updated
.
Post not yet marked as solved
3 Replies
1.1k Views
I have a multiplatform SwiftUI document app project. My app has a custom document type and can export to another type. I have both types in the document’s list of writable content types. When I save the document, the save panel on Mac has a File Format menu to save the file with an item for each writable content type. But the only type the document should save to is my custom document type. If someone chooses the exported type, they won’t be able to open the document. How do I limit the Save panel to save the document only in my custom document type? I tried removing the exported type from the list of writable content types, but when I export the file, I get the following error message in Xcode’s console: Attempting to export a document using a content type not included in its writableContentTypes. The first supported writable content type will be used instead. The export works, but the file has the extension for my custom document type. Changing the file extension in the Finder makes everything work. But I don’t want people to have to manually change file extensions. I tried taking the URL SwiftUI’s file exporter returns and changing the file extension, but I get the same error message in Xcode’s console. The exported file still has the extension for my custom document type. I also tried adding the exported type to the list of writable content types when exporting, but the writable content types array can’t be modified at runtime. What do I have to do to save documents only as my custom document type while exporting with the correct file extension?
Posted
by szymczyk.
Last updated
.
Post not yet marked as solved
0 Replies
803 Views
I have a document-based SwiftUI app where the document is a file wrapper. The document has the following writable content types: static var writableContentTypes: [UTType] { [.bookDocumentPackage, .epub, .pdf] } I am using .fileExporter to export the document to PDF. .fileExporter(isPresented: $isPublishing,     document: book,     contentType: .pdf,     defaultFilename: book.metadata.title) { result in     switch result { case .success(let url):             book.publishPDF(location: url)         case .failure(let error):             print(error.localizedDescription)     } } The problem is the URL the file exporter returns is treated as a directory instead of a file. I have the following code to create a PDF context to create the PDF: func buildPDFContext(url: URL) -> CGContext? {     // For now, just go with a standard 8.5 by 11 inch page.     let pdfContext = CGContext(url as CFURL, mediaBox: nil, nil)     return pdfContext } When I call the function, I get the following error message in Xcode’s debug console: CGDataConsumerCreateWithFilename: failed to open /URL/from/fileExporter for writing: Is a directory. The PDF context is not created. Instead of a PDF file, I get my document file wrapper as a collection of files and folders. I can work around this problem on Mac by using NSSavePanel instead of SwiftUI’s file exporter. But iOS has no equivalent to NSSavePanel. I tried using the FileManager class to create an empty file at the URL and use that to create the PDF, but the URL is still treated as a directory. I also tried making PDF the only writable content type, but the error persists. How do I get the URL the file exporter returns to be treated as a file instead of a directory?
Posted
by szymczyk.
Last updated
.
Post marked as solved
7 Replies
1.3k Views
Many people post questions on these forums that have detailed answers in articles and blog posts from people who aren't Apple employees. It would be nice to link to these articles when answering questions on these forums. But if you try to link to a non-Apple URL, you get an error message that the domain is invalid. To post the link, you have to remove the https://www part of the link. This forces people to cut and paste the URL into the browser to read the article when they should get a clickable link. If you're worried about spam links, then either require posters to have a minimum reputation score or have a minimum number of posts to submit answers with external links.
Posted
by szymczyk.
Last updated
.
Post marked as solved
2 Replies
1.9k Views
I want to display a currency value in a SwiftUI app. I created a currency formatter. I created a text field, set its formatter to the currency formatter I created, and disabled the text field so people couldn't edit it. let currencyFormatter: NumberFormatter = { let formatter = NumberFormatter() formatter.numberStyle = .currency return formatter }() TextField("Tip Amount", value: $tipAmount, formatter: currencyFormatter) .disabled(true) This works well on iOS. The currency formatter works correctly. I can see the value clearly and can't change it. But on Mac the text in the disabled text field is virtually unreadable. I just want to display the value so I don't need a text field. I could use a Text view. But Text views don't support formatters as far as I can tell. How do I show a currency value with SwiftUI on Mac with readable text?
Posted
by szymczyk.
Last updated
.
Post not yet marked as solved
0 Replies
1.2k Views
Xcode 13.2 adds the Swift Playgrounds App project template that works with the upcoming version of Swift Playgrounds. The project template creates an iOS SwiftUI app. SwiftUI has a sprite view to show SpriteKit scenes so I tried adding a new SpriteKit scene to the project. Choosing File > New > File adds a Swift file to the project. The New File Assistant doesn't open. I can add an existing SpriteKit scene to the project. I can view and edit the scene. I can also show the scene in a sprite view so I know this project template supports SpriteKit. Adding an existing SpriteKit scene also adds a Resources folder to the project. When I choose to create a new file from the Resources folder, the New File Assistant opens. But SpriteKit Scene is not one of the file types I can add. How do I add a new SpriteKit scene file to a Swift Playgrounds App project?
Posted
by szymczyk.
Last updated
.
Post marked as solved
1 Replies
1.3k Views
I have a multiplatform document-based SwiftUI app. I have a custom document type with its own file extension that saves documents as file packages that appears as a single file in the Finder or Files app. The app exports documents as EPUB books. The document type, exported type identifier, and imported type identifier settings are the same for the iOS and Mac app targets.  I have the following code in my document struct for dealing with the document types: extension UTType { static var bookDocument: UTType { UTType(importedAs: "com.MyConpany.book")     } } static var readableContentTypes: [UTType] { [.bookDocument] } static var writableContentTypes: [UTType] { [.epub] } Everything works right on iOS. The documents appear as single files in the Files app and have my custom file extension. But on Mac the documents have the extension .epub. When I try to open a document from the Finder, the Books app launches instead of opening the document in my app. The document fails to open in the Books app because it’s not an EPUB book. Fix Attempt 1 I figured the document has the .epub extension because it’s the only writable content type for the document. I tried adding my document type to the list of writable content types. static var writableContentTypes: [UTType] { [.bookDocument, .epub]} But the document’s file extension changes to .iba, which is iBooks Author format. Opening the document in the Finder launches Pages instead of my app. From past experience the iBooks Author format is the default document format when no writable content types are supplied. Fix Attempt 2 My next attempt was to create a UTType with my custom file extension, conform to package, and add that to the writable content types array. static var bookDocumentPackage: UTType { UTType(filenameExtension: "swiftbook", conformingTo: .package)! } static var writableContentTypes: [UTType] { [.bookDocumentPackage, .epub] } But the document appears as a folder in the Finder instead of a single file. Fix Attempt 3 My next attempt was to create a UTType that exports to my custom document type and conforms to package. static var bookDocumentPackage: UTType { UTType(exportedAs: "com.MyCompany.book", conformingTo: .package) } But the document has the extension .book. Doing a Get Info on the document in the Finder shows it’s in iBooks Author format. Question What do I have to do with the UTTypes to get my document to appear as a single file in the Finder with my custom file extension?
Posted
by szymczyk.
Last updated
.
Post not yet marked as solved
2 Replies
1.5k Views
I'm working on a document-based SwiftUI app for Mac and iOS that uses SwiftUI's TextEditor for entering text. I want to insert markup, such as Markdown formatting, into the text editor. For example in Markdown to create bold text, I would select the text, press Cmd-B (or use a button or menu), and insert the asterisks at the start and the end of the selection. With NSTextViewand UITextView I can access the range of the selection using the selectedRange property. But looking through the documentation for TextEditor, I see no way of getting the range of the selection. Without the selection range there's no way for me to insert the markup in the correct position. How do I get the range of the selection in a SwiftUI text editor?
Posted
by szymczyk.
Last updated
.
Post marked as solved
2 Replies
1.7k Views
In my SwiftUI app I have a view for people to edit a book's metadata, such as its title and author. In this view I have an image view that shows the book's cover image. struct ImageView: View {     @Binding var book: Book var body: some View { // coverImage is the URL to the image file. let image = NSImage(byReferencing: book.metadata.coverFile) Image(nsImage: image) .aspectRatio(contentMode: .fit) } } When I open a book that I've set a cover image and open the metadata editor, the image view displays nothing. The metadata editor has a button to choose a cover image. When I click the button and choose an image file from the file importer, the image appears in the image view. If I close the book, reopen it, and open the metadata editor, the image appears in the image view. But if I restart the app, open the book, and open the metadata editor, the image view displays nothing. I have tried the various NSImage initializers. I tried building the image from a Data object and from NSBitmapImageRep. But when I set a breakpoint in the image view and check the image variable, it's either nil or invalid. When I check the coverfile variable, it displays the proper URL, including the .png extension. In an AppKit version of this app, I have the same code to create the NSImage, and the image displays in the image view. How do I get an existing image file to display in the image view without clicking the Choose Cover button and choosing the file again from the file importer?
Posted
by szymczyk.
Last updated
.
Post marked as solved
3 Replies
1.1k Views
I am trying to notarize a Mac app on Xcode 12.2. I archive the app, open the Organizer, select the archive and click the Distribute App button. I go through the steps in the wizard. Everything goes well until I click the Upload button to upload the app to Apple to notarize. When I click the Upload button, I get the following error: App Store Connect Operation Error Could not find or load main class Followed by a path to the Library.Java.Extensions folder on my Mac. I have tried cleaning the build folder and creating a fresh archive, but the upload error persists. How do I fix this error?
Posted
by szymczyk.
Last updated
.
Post marked as solved
10 Replies
4.1k Views
I'm trying to export a text document in the Documents directory and running into file permission problem in a Mac app that does not use the App Sandbox. As a workaround for the issue, I tried turning on the App Sandbox and giving read/write access to the Documents directory, but when I add the App Sandbox capability, I have the following entries for file access: User Selected File Downloads Folder Pictures Folder Music Folder Movies Folder Since the file is a text file, exporting to any of the folders in the list makes no sense. If I give User Selected File read/write access, I still get file permission errors when I export. The UI in Xcode provides no way to add folders to the File Access list. All I want to do is let someone export a file in the folder of their choice. How do I do this with the App Sandbox? UPDATE I'm developing a SwiftUI app. I was using SwiftUI's file exporter to export the document. I took robnotyou's suggestion to use NSSavePanel, but I still get the file permission error, with or without the App Sandbox. I get the following message in Xcode's console: Error: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file If I turn on the App Sandbox, give the Downloads folder read/write permission, and export the document there, the file permissions issue goes away. I'm running macOS 11.5.2. If I open the Privacy preferences in System Preferences and select Files and Folders, I can see that some previous apps I developed appear in the list and have a checkbox selected that grants the app access to the Documents folder. The list of apps has an Add button, but it's disabled. I tried giving this app full disk access and adding it to the Developer Tools list of apps that can run software locally that does not meet the system's security policy. But the file permission error persists. I'm exporting the file in a folder inside the Documents directory. The file has read/write access for my user account and my group. The Documents folder has custom access when I get info on the folder in the file. How do I get around this file permission error?
Posted
by szymczyk.
Last updated
.