I have a SwiftUI app. It fetches records through CoreData. And I want to show some records on a widget. I understand that I need to use AppGroup to share data between an app and its associated widget.
import Foundation
import CoreData
import CloudKit
class DataManager {
static let instance = DataManager()
let container: NSPersistentContainer
let context: NSManagedObjectContext
init() {
container = NSPersistentCloudKitContainer(name: "DataMama")
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: group identifier)!.appendingPathComponent("Trash.sqlite"))]
container.loadPersistentStores(completionHandler: { (description, error) in
if let error = error as NSError? {
print("Unresolved error \(error), \(error.userInfo)")
}
})
context = container.viewContext
context.automaticallyMergesChangesFromParent = true
context.mergePolicy = NSMergePolicy(merge: .mergeByPropertyObjectTrumpMergePolicyType)
}
func save() {
do {
try container.viewContext.save()
print("Saved successfully")
} catch {
print("Error in saving data: \(error.localizedDescription)")
}
}
}
// ViewModel //
import Foundation
import CoreData
import WidgetKit
class ViewModel: ObservableObject {
let manager = DataManager()
@Published var records: [Little] = []
init() {
fetchRecords()
}
func fetchRecords() {
let request = NSFetchRequest<Little>(entityName: "Little")
do {
records = try manager.context.fetch(request)
records.sort { lhs, rhs in
lhs.trashDate! < rhs.trashDate!
}
} catch {
print("Fetch error for DataManager: \(error.localizedDescription)")
}
WidgetCenter.shared.reloadAllTimelines()
}
}
So I have a view model that fetches data for the app as shown above.
Now, my question is how should my widget get data from CoreData? Should the widget get data from CoreData through DataManager? I have read some questions here and also read some articles around the world. This article ( https://dev.classmethod.jp/articles/widget-coredate-introduction/ ) suggests that you let the Widget struct access CoreData through DataManager. If that's a correct fashion, how should the getTimeline function in the TimelineProvider struct get data? This question also suggests the same. Thank you for your reading my question.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have three toolbar buttons with images from Assets.xcassets. Initially, I didn't use @1x, @2x, @3x sizes. I just put one size (72 x 72) for all of them. It was never a problem till a few days ago.
The reviewer has reported numerous issues, which all seem to originate from miniaturized toolbar images. They have given me a screenshot from an iPad. Now, each of the three to the left has shrunken to 4 x 4, according to them.
Some lines of code are the following.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
ZStack {
VStack {
...
...
...
}
.background(.brown)
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(
leading: HStack(content: {
Button {
} label: {
Image("ToolbarImage1")
.resizable()
.foregroundColor(.red)
.aspectRatio(contentMode: .fit)
.frame(width: 28)
}
Button {
} label: {
Image("ToolbarImage2")
.resizable()
.foregroundColor(.cyan)
.aspectRatio(contentMode: .fit)
.frame(width: 28)
}
Button {
} label: {
Image("ToolbarImage3")
.resizable()
.foregroundColor(.gray)
.aspectRatio(contentMode: .fit)
.frame(width: 28)
}
}),
trailing: HStack(content: {
Button {
} label: {
Text("X")
.font(.body)
.fontWeight(.semibold)
.foregroundStyle(colorScheme == .light ? .white : .black)
.frame(width: 28, height: 28)
.background {
Circle()
.fill(!disableGroupMenu ? .green : .green.opacity(0.6))
}
}
Button {
withAnimation(.easeInOut(duration: 0.2)) {
showCopyMenu.toggle()
manageMenu()
}
} label: {
Text("Y")
.font(.body)
.fontWeight(.semibold)
.foregroundStyle(colorScheme == .light ? .white : .black)
.frame(width: 28, height: 28)
.background {
Circle()
.fill(!disableCopyMenu ? .indigo: .indigo.opacity(0.6))
}
}
})
)
.toolbar {
ToolbarItem(placement: .principal) {
Text("App name")
.bold()
.foregroundColor(.white)
}
}
}
}
}
}
I don't see this minituralization issue on any of my actual devices (iPhone XR, iPhone 14, iPad 9th gen.) on top of various simulator models including iPad A16 with iOS 26. This is my first iOS submission after iOS 26 was released. I don't know if it has something to do with iOS 26. The reviewer hasn't told me about their iPad model or the iOS version. I have the same app for macOS, which was submitted after macOS 26 was released. And they haven't reported the miniaturization issue after 4 or 5 software updates.
If you have any idea as to what's causing it, please let me know. I have submitted a new binary with @3x as a resort. I doubt the issue has been resolved. Thanks.
Initally, I've used Xcode 16.4 to built the app. I have tried building it with Xcode 26. And I don't see the minituralization issue on any of the simulator models (iPad mini, iPad A16...).
Topic:
UI Frameworks
SubTopic:
SwiftUI
I've been waiting since I had Organizer sent my latest IPA to iTunes Connect servers 40 minutes ago. But the App Store Connect site doesn't show it. Is anyone having the same issue? I hate it when it happens because you don't know how long you have to wait.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
I've been trying to send an archive with Organizer to iTunes Connect. It's not my first time. I've been doing it for more than a decade. Anyway, when I try to send a package for my new macOS application, Organizer gives me two error messages that I have never seen before.
App Record Creation Error
App Record Creation failed due to an invalid attribute. The SKU you entered has already been used.
App Record Creation Error
App Record Creation failed due to request containing an attribute already in use. The app name you entered is already being used for another app in your account. If you would like to use the name for this app you will need to submit an update to your other app to change the name, or remove it from App Store Connect.
An odd thing is that, as shown in the screenshot below, Organizer demands that I enter an application name and SKU manually. I've entered the exactly same ones from the App Store Connect page. I didn't see this step on Organizer last month.
I'm using a new SKU for this submission. And I don't have an existing application at iTunes Connect with the same application name.
I guess it's the same issue that has been reported here.. I have no pending contract issues.
How do I send an archive without errors? My Xcode version is Version 16.4 (16F6).
Thanks.
Do you let your users restore their IAP purchases with or without history of purchases? I don't. And it had not been a problem in the past 10 years or so till two days ago when the reviewer rejected my new iOS software submission. He or she said that it was a bug since the Restore button is disabled. I saw the screenshot he or she gave me in which it was obvious that the reviewer had not made a purchase.
For me, I cannot think of a reason why one with no history of purchases should be allowed to proceed and restore purchases. I don't even know what the reviewer is trying to restore. So far, the reviewer doesn't buy my explanation or seems to ignore me. What do you think? Do you let them go lucky by accident? By the way, this is a non-consumable IAP product.
Topic:
App Store Distribution & Marketing
SubTopic:
App Review
A few weeks ago, I explored the possibility of installing auto-renewal subscription plans on an iOS app. Initially, I thought subscription plans are allowed for news and magazine apps. Then I saw this Apple website, which actually encourages us to provide 'free, limited access to app content.' So I took their advice and submitted an iOS app that has no dynamic content to App Store. I submitted another. Two apps have been approved. And I have got the third one put on hold several days ago. The reviewer has asked me an uncomfortable line of questions repeatedly like
What are changes?
How often?
that I have never received in my 13 or 14 year history. Then he or she rejected it two days ago. And I got a 4th one approved at the same time. So three are admitted in with one rejected.
Does an app have to have dynamic content to use auto-renewal subscription plans? I don't find any statement in Apple Review Guidelines that prohibits me from installing auto-renewal subscription plans on non-dynamic content app. There are other big-time apps like Microsoft 365 and Adobe Photoshop that are available with subscription plans. I am very perplexed.
I've submitted my first AR app for iPhone and iPad to iTunes Connect. After sending a binary to iTunes Connect, I've received the following warning message.
The app contains the following UIRequiredDeviceCapabilities values, which aren’t supported in visionOS: [arkit].
No. 1, my app doesn't support visionOS. No. 2, I don't have the UIRequiredDeviceCapabilities dictionary in info.plist. Why am I receiving this warning? One article related to this issue that I've read suggests that I remove the UIRequiredDeviceCapabilities dictionary. Well, I don't have it in my plist. What can I do with this warning message? Thanks.
Topic:
Spatial Computing
SubTopic:
ARKit
I'm a novice in RealityKit and ARKit. I'm using ARKit in SwiftUI to show a cube with a number as shown below.
import SwiftUI
import RealityKit
import ARKit
struct ContentView : View {
var body: some View {
return ARViewContainer()
}
}
#Preview {
ContentView()
}
struct ARViewContainer: UIViewRepresentable {
typealias UIViewType = ARView
func makeUIView(context: UIViewRepresentableContext<ARViewContainer>) -> ARView {
let arView = ARView(frame: .zero, cameraMode: .ar, automaticallyConfigureSession: true)
arView.enableTapGesture()
return arView
}
func updateUIView(_ uiView: ARView, context: UIViewRepresentableContext<ARViewContainer>) {
}
}
extension ARView {
func enableTapGesture() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:)))
self.addGestureRecognizer(tapGestureRecognizer)
}
@objc func handleTap(recognizer: UITapGestureRecognizer) {
let tapLocation = recognizer.location(in: self) // print("Tap location: \(tapLocation)")
guard let rayResult = self.ray(through: tapLocation) else { return }
let results = self.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .any)
if let firstResult = results.first {
let position = simd_make_float3(firstResult.worldTransform.columns.3)
placeObject(at: position)
}
}
func placeObject(at position: SIMD3<Float>) {
let mesh = MeshResource.generateBox(size: 0.3)
let material = SimpleMaterial(color: UIColor.systemRed, roughness: 0.3, isMetallic: true)
let modelEntity = ModelEntity(mesh: mesh, materials: [material])
var unlitMaterial = UnlitMaterial()
if let textureResource = generateTextResource(text: "1", textColor: UIColor.white) {
unlitMaterial.color = .init(tint: .white, texture: .init(textureResource))
modelEntity.model?.materials = [unlitMaterial]
let id = UUID().uuidString
modelEntity.name = id
modelEntity.transform.scale = [0.3, 0.1, 0.3]
modelEntity.generateCollisionShapes(recursive: true)
let anchorEntity = AnchorEntity(world: position)
anchorEntity.addChild(modelEntity)
self.scene.addAnchor(anchorEntity)
}
}
func generateTextResource(text: String, textColor: UIColor) -> TextureResource? {
if let image = text.image(withAttributes: [NSAttributedString.Key.foregroundColor: textColor], size: CGSize(width: 18, height: 18)), let cgImage = image.cgImage {
let textureResource = try? TextureResource(image: cgImage, options: TextureResource.CreateOptions.init(semantic: nil))
return textureResource
}
return nil
}
}
I tap the floor and get a cube with '1' as shown below.
The background color of the cube is black, I guess. Where does this color come from and how can I change it into, say, red? Thanks.
The other day I was playing with iBeacon and found out that CLBeaconIdentityConstraint will be deprecated after iOS 18.5. So I've written code with BeaconIdentityCondition in reference to this Apple's sample project.
import Foundation
import CoreLocation
let monitorName = "BeaconMonitor"
@MainActor
public class BeaconViewModel: ObservableObject {
private let manager: CLLocationManager
static let shared = BeaconViewModel()
public var monitor: CLMonitor?
@Published var UIRows: [String: [CLMonitor.Event]] = [:]
init() {
self.manager = CLLocationManager()
self.manager.requestWhenInUseAuthorization()
}
func startMonitoringConditions() {
Task {
print("Set up monitor")
monitor = await CLMonitor(monitorName)
await monitor!.add(getBeaconIdentityCondition(), identifier: "TestBeacon")
for identifier in await monitor!.identifiers {
guard let lastEvent = await monitor!.record(for: identifier)?.lastEvent else { continue }
UIRows[identifier] = [lastEvent]
}
for try await event in await monitor!.events {
guard let lastEvent = await monitor!.record(for: event.identifier)?.lastEvent else { continue }
if event.state == lastEvent.state {
continue
}
UIRows[event.identifier] = [event]
UIRows[event.identifier]?.append(lastEvent)
}
}
}
func updateRecords() async {
UIRows = [:]
for identifier in await monitor?.identifiers ?? [] {
guard let lastEvent = await monitor!.record(for: identifier)?.lastEvent else { continue }
UIRows[identifier] = [lastEvent]
}
}
func getBeaconIdentityCondition() -> CLMonitor.BeaconIdentityCondition {
CLMonitor.BeaconIdentityCondition(uuid: UUID(uuidString: "abc")!, major: 123, minor: 789)
}
}
It works except that my sample app can take as long as 90 seconds to see event changes. You would get an instant update with an fashion (CLBeacon and CLBeaconIdentityConstraint). Is there anything that I can do to see changes faster? Thanks.
I have an NSStatusBar application. This is my first in SwiftUI. And I need to know when the window is closed so that I can disable some of menu commands. I can use NSWindowDelegate with AppDelegate as follows.
import SwiftUI
@main
struct SomeApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject private var menuViewModel = MenuViewModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(menuViewModel)
}
}
}
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
private var menuViewModel = MenuViewModel()
func applicationDidFinishLaunching(_ notification: Notification) {
if let window = NSApplication.shared.windows.first {
window.setIsVisible(false)
window.delegate = self
}
}
func windowWillClose(_ notification: Notification) {
menuViewModel.windowClosed = true
}
}
When the window will close, MenuViewModel (ObservableObject) will receive a call, which I want my ContentView to receive. But, so far, it won't.
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
...
...
}
.onReceive(statusBarViewModel.$windowClosed) { result in
// never called...
}
}
}
Can a SwiftUI View receive a call somehow when its window closes? Muchos thankos.
In reference to this webpage, I'm turning my iPad to an iBeacon device.
class BeaconViewModel: NSObject, ObservableObject, CBPeripheralManagerDelegate {
private var peripheralManager: CBPeripheralManager?
private var beaconRegion: CLBeaconRegion?
private var beaconIdentityConstraint: CLBeaconIdentityConstraint?
//private var beaconCondition: CLBeaconIdentityCondition?
override init() {
super.init()
if let uuid = UUID(uuidString: "abc") {
beaconIdentityConstraint = CLBeaconIdentityConstraint(uuid: uuid, major: 123, minor: 456)
beaconRegion = CLBeaconRegion(beaconIdentityConstraint: beaconIdentityConstraint!, identifier: "com.example.myDeviceRegion")
peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
}
}
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
switch peripheral.state {
case .poweredOn:
startAdvertise()
case .poweredOff:
peripheralManager?.stopAdvertising()
default:
break
}
}
func startAdvertise() {
guard let beaconRegion = beaconRegion else { return }
let peripheralData = beaconRegion.peripheralData(withMeasuredPower: nil)
peripheralManager?.startAdvertising(((peripheralData as NSDictionary) as! [String: Any]))
}
func stopAdvertise() {
peripheralManager?.stopAdvertising()
}
}
In Line 10, I'm using CLBeaconidentityConstraint to constrain the beacon. Xcode says that this class is deprecated and suggests that we use CLBeaconIdentityCondition. But if I try to use it, Xcode says
Cannot find type 'CLBeaconIdentityCondition' in scope
I've just updated Xcode to 16.4. I still get the same error. So how do we use CLBeaconIdentityCondition to constrain the beacon? My macOS version is Sequoia 15.5. Thanks.
I have a macOS application developed in SwiftUI. It's a document-based application. I know how to hide the Show Tab Bar command under View. I don't want to hide it. I always want to show tabs. I wonder how to enable this command programmatically such that the document window always has the + button to the right. Thanks.
Its document says openDocument can open a document at a specific URL. So I've saved a model as a JSON object with its URL and a bookmark as Data. With its security-scoped bookmark data resolved, I am able to open a document except that the app will crash right after opening a document. Console says
should only be called in the main thread
struct ContentView: View {
@EnvironmentObject var bookmarkViewModel: BookmarkViewModel
var body: some View {
VStack {
}
.onAppear {
loadBookmarks()
}
}
extension ContentView {
func loadBookmarks() {
print("1 \(Thread.current)") // NSMainThread
Task {
for bookmarkItem in bookmarkViewModel.bookmarkItems { // resolving a security-scoped bookmark
print("2 \(Thread.current)") // NSMainThread
if let _ = resolveBookmark(bookmarkData: bookmarkItem.bookmarkData) {
print("3 \(Thread.current)") // NSMainThread
do {
print("4 \(Thread.current)") // NSMainThread
try await openDocument(at: bookmarkItem.bookmarkURL)
print("5 \(Thread.current)") // NSMainThread
} catch {
print("\(error.localizedDescription)")
}
}
}
}
}
}
Well, the application is on the main thread. I've checked every line before and after opening a document with its URL. Call what on the main thread? This is confusing. Thanks.
class BookmarkViewModel: ObservableObject {
@Published var bookmarkItems: [BookmarkItem] = []
var defaultFileManager: FileManager {
return FileManager.default
}
var documentURL: URL? {
...
}
init() {
fetchBookmarkItems()
}
func fetchBookmarkItems() {
bookmarkItems.removeAll()
if let documentURL {
let bookmarkFolderURL = documentURL.appending(path: "MyApp").appending(path: "Bookmarks")
do {
let contents = try defaultFileManager.contentsOfDirectory(atPath: bookmarkFolderURL.path)
for content in contents {
...
let fileURL = bookmarkFolderURL.appending(path: content)
let data = try Data(contentsOf: fileURL)
let bookmarkItem = try JSONDecoder().decode(BookmarkItem.self, from: data)
bookmarkItems.append(bookmarkItem)
}
} catch {
print("Error fetching folder content: \(error.localizedDescription)")
}
}
}
}
struct BookmarkItem: Codable, Hashable {
let bookmarkURL: URL
let date: Date
let bookmarkData: Data
let open: Bool
}
I need to check the network connection with NWPathMonitor.
import Foundation
import Network
class NetworkViewModel: ObservableObject {
let monitor = NWPathMonitor()
let queue = DispatchQueue(label: "NetworkViewModel")
@Published var isConnected = false
var connectionDescription: String {
if isConnected {
return "You are connected."
} else {
return "You are NOT connected."
}
}
init() {
monitor.pathUpdateHandler = { path in
DispatchQueue.main.async {
self.isConnected = path.status == .satisfied
}
}
monitor.start(queue: queue)
}
}
import SwiftUI
struct ContentView: View {
@StateObject private var networkViewModel = NetworkViewModel()
var body: some View {
VStack {
}
.onAppear {
if networkViewModel.isConnected {
print("You are connected.")
}
else {
print("You are NOT connected.")
}
}
}
}
So there is nothing special, not at all. Yet, if I test it with a totally new Xcode project for iOS, it fails and return !isConnected. I've tested it with a macOS application. And it fails. I've tested it with an actual device. It fails. I've tested it with an old project. It still does work. I have no mere idea why new Xcode projects all fail to detect the WiFi connection. This is a total nightmare. Does anybody have a clue? thanks.
I'm working on an iOS app with a Widget. I am able to display the Widget on the iPhone 16 Pro Simulator. It doesn't appear on iPad mini 6th gen., though. Anyway, I want to make sure that it works on an actual device. If I try to add the Widget to the Home Screen, I cannot find it in the search list on iPhone XR and iPad 9th gen. If I set the target to that of the widget, Xcode gives me the following error.
SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 "Failed to show Widget 'some bundle ID' error: …
I hope that's not a sign of trouble. So how do you debug a Widget on an Actual Device? I've read some topics like this one here. Thanks.