Hello
I'm trying to schedule a local notification to fire every day, at a specific time, but from tomorrow.
e.g. "Trigger a notification every day at 2 pm, from tomorrow"
This is how I set up my schedule function.
func scheduleNotifications(date: Date, identfier: String, after: Bool) {
let content = UNMutableNotificationContent()
content.title = "App"
content.body = "Test"
content.sound = .default
content.userInfo = ["Hour": Int(hourFormatter.string(from: date)) ?? 0]
let afterDay = Calendar.current.date(byAdding: .day, value: after ? 1 : 0, to: Date())
var components = Calendar.current.dateComponents([.hour, .minute], from: afterDay!)
components.hour = Int(hourFormatter.string(from: date)) ?? 0
components.minute = Int(minuteFormatter.string(from: date)) ?? 0
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
let request = UNNotificationRequest(identifier: identfier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello
I have an app that uses Core Data with CloudKit to store data. When I am in the app (using the app) and create some new data on an other device, the data is fetched in a few seconds and I see it immediately, however if I am not using the app and create some new data on an other device, I have to enter the app and then the data starts fetching, is there a way to fetch data even if I am not using the app.
Here is my core data stack:
import CoreData
import Combine
class PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentCloudKitContainer
init() {
container = NSPersistentCloudKitContainer(name: "CoreData")
guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "APP_GROUP_NAME")?.appendingPathComponent("CoreData.sqlite") else {
fatalError("Shared file container could not be created.")
}
let storeDescription = NSPersistentStoreDescription(url: fileContainer)
storeDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
storeDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
storeDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "Container_Identifier")
container.persistentStoreDescriptions = [storeDescription]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
}
}
Hello
I have this Core Data stack and I have an observer to observe NSPersistentStoreRemoteChange, I would like to filter changes that the user has made to call the mergePersistentHistoryChanges() just when needed, I think it has to be done in the fetchPersistentHistoryTransactionsAndChanges() function but I don't know how to do it. Can you help me. Thank You
Here is my Core Data Stack:
class PersistenceController {
static let shared = PersistenceController()
private var notificationToken: NSObjectProtocol?
init() {
notificationToken = NotificationCenter.default.addObserver(forName: .NSPersistentStoreRemoteChange, object: nil, queue: nil) { note in
Task {
await self.fetchPersistentHistory()
}
}
}
deinit {
if let observer = notificationToken {
NotificationCenter.default.removeObserver(observer)
}
}
private var lastToken: NSPersistentHistoryToken?
/// A persistent container to set up the Core Data stack.
lazy var container: NSPersistentCloudKitContainer = {
let fileContainer = URL.storeURL(for: "group name", databaseName: "CoreData")
let container = NSPersistentCloudKitContainer(name: "CoreData")
let defaultDirectoryURL = NSPersistentContainer.defaultDirectoryURL()
let localStoreURL = defaultDirectoryURL.appendingPathComponent("Local.sqlite")
let localStoreDescription = NSPersistentStoreDescription(url: localStoreURL)
localStoreDescription.configuration = "Local"
// Create a store description for a CloudKit-backed local store
let cloudStoreDescription = NSPersistentStoreDescription(url: fileContainer)
cloudStoreDescription.configuration = "Cloud"
// Set the container options on the cloud store
cloudStoreDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "containerIdentifier")
cloudStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
cloudStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.persistentStoreDescriptions = [cloudStoreDescription, localStoreDescription]
container.loadPersistentStores { storeDescription, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
// This sample refreshes UI by consuming store changes via persistent history tracking.
/// - Tag: viewContextMergeParentChanges
container.viewContext.automaticallyMergesChangesFromParent = false
container.viewContext.name = "viewContext"
container.viewContext.transactionAuthor = "User"
/// - Tag: viewContextMergePolicy
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.undoManager = nil
container.viewContext.shouldDeleteInaccessibleFaults = true
return container
}()
private func newTaskContext() -> NSManagedObjectContext {
// Create a private queue context.
/// - Tag: newBackgroundContext
let taskContext = container.newBackgroundContext()
taskContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
// Set unused undoManager to nil for macOS (it is nil by default on iOS)
// to reduce resource requirements.
taskContext.undoManager = nil
return taskContext
}
func save() {
if self.container.viewContext.hasChanges {
do {
try self.container.viewContext.save()
} catch {
print(Errors.errorSaving)
}
}
}
func fetchPersistentHistory() async {
do {
try await fetchPersistentHistoryTransactionsAndChanges()
} catch {
print(Errors.fetchPersistentHistory)
}
}
private func fetchPersistentHistoryTransactionsAndChanges() async throws {
let taskContext = newTaskContext()
taskContext.name = "persistentHistoryContext"
try await taskContext.perform {
let changeRequest = NSPersistentHistoryChangeRequest.fetchHistory(after: self.lastToken)
let historyResult = try taskContext.execute(changeRequest) as? NSPersistentHistoryResult
if let history = historyResult?.result as? [NSPersistentHistoryTransaction],
!history.isEmpty {
self.mergePersistentHistoryChanges(from: history)
return
}
throw Errors.fetchPersistentHistoryTransactionsAndChanges
}
}
private func mergePersistentHistoryChanges(from history: [NSPersistentHistoryTransaction]) {
let viewContext = container.viewContext
viewContext.perform {
for transaction in history {
print("Merged by func mergePersistentHistoryChanges ")
viewContext.mergeChanges(fromContextDidSave: transaction.objectIDNotification())
self.lastToken = transaction.token
}
}
}
}
Hello
I have a function to add data to Core Data that has a completion and uses Futures, I wanted to know what is the best way to convert it to use async, because I just started learning how to use async and await. (I am not really sure how to do it)
Here is the function:
func add(context: NSManagedObjectContext, _ body: @escaping (inout Entity) -> Void) -> AnyPublisher<Entity, Error> {
Deferred { [context] in
Future { promise in
context.perform {
var entity = Entity(context: context)
body(&entity)
do {
try context.save()
promise(.success(entity))
} catch {
promise(.failure(error))
}
}
}
}
.eraseToAnyPublisher()
}
Thank You
Hello
What is the best framework for indoor geofencing (with iBeacons devices)? Would the SensorKit framework be any good?
I'm trying to build an indoor geofencing app that uses UWB or BLE devices.
I am thinking of the SensorKit framework because it is used for research and studies and I am looking for the best way to realize indoor geofencing (preferably using UWB devices). The app should also work while it's in the background.
Thank you!
Hello
I am building a study research app that tracks data of different users. The data is saved through Core Data (with relationships) and I was wondering if there was a way to view all the data through CloudKit?
I know I can use public databases with CloudKit in CoreData but was wondering if that would merge all the data of the different users, and if that is the case how would I deal with it?
If that is not possible how would I download all the data in a PDF that the user can send?
Thanks for your help
Hi everyone,
I’m building a full-screen Map (MapKit + SwiftUI) with persistent top/bottom chrome (menu buttons on top, session stats + map controls on bottom). I have three working implementations and I’d like guidance on which pattern Apple recommends long-term (gesture correctness, safe areas, Dynamic Island/home indicator, and future compatibility).
Version 1 — overlay(alignment:) on Map
Idea: Draw chrome using .overlay(alignment:) directly on the map and manage padding manually.
Map(position: $viewModel.previewMapCameraPosition, scope: mapScope) {
UserAnnotation {
UserLocationCourseMarkerView(angle: viewModel.userCourse - mapHeading)
}
}
.mapStyle(viewModel.mapType.mapStyle)
.mapControls {
MapUserLocationButton().mapControlVisibility(.hidden)
MapCompass().mapControlVisibility(.hidden)
MapPitchToggle().mapControlVisibility(.hidden)
MapScaleView().mapControlVisibility(.hidden)
}
.overlay(alignment: .top) { mapMenu } // manual padding inside
.overlay(alignment: .bottom) { bottomChrome } // manual padding inside
Version 2 — ZStack + .safeAreaPadding
Idea: Place the map at the back, then lay out top/bottom chrome in a VStack inside a ZStack, and use .safeAreaPadding(.all) so content respects safe areas.
ZStack(alignment: .top) {
Map(...).ignoresSafeArea()
VStack {
mapMenu
Spacer()
bottomChrome
}
.safeAreaPadding(.all)
}
Version 3 — .safeAreaInset on the Map
Idea: Make the map full-bleed and then reserve top/bottom space with safeAreaInset, letting SwiftUI manage insets
Map(...).ignoresSafeArea()
.mapStyle(viewModel.mapType.mapStyle)
.mapControls {
MapUserLocationButton().mapControlVisibility(.hidden)
MapCompass().mapControlVisibility(.hidden)
MapPitchToggle().mapControlVisibility(.hidden)
MapScaleView().mapControlVisibility(.hidden)
}
.safeAreaInset(edge: .top) { mapMenu } // manual padding inside
.safeAreaInset(edge: .bottom) { bottomChrome } // manual padding inside
Question
I noticed:
Safe-area / padding behavior
– Version 2 requires the least extra padding and seems to create a small but partial safe-area spacing automatically.
– Version 3 still needs roughly the same manual padding as Version 1, even though it uses safeAreaInset. Why doesn’t safeAreaInset fully handle that spacing?
Rotation crash (Metal)
When using Version 3 (safeAreaInset + ignoresSafeArea), rotating the device portrait↔landscape several times triggers a
Metal crash:
failed assertion 'The following Metal object is being destroyed while still required… CAMetalLayer Display Drawable'
The same crash can happen with Version 1, though less often. I haven’t tested it much with Version 2.
Is this a known issue or race condition between Map’s internal Metal rendering and view layout changes?
Expected behavior
What’s the intended or supported interaction between safeAreaInset, safeAreaPadding, and overlay when embedding persistent chrome inside a SwiftUI Map?
Should safeAreaInset normally remove the need for manual padding, or is that by design?
Hello
I'm making an app that displays large Double numbers, for example 86,859.002. The problem is how do I change the comma( , ) with the dot ( . )
Thank you
Hello
I'm trying to decode a JSON File but it's not working and I can't understand why
Code:
import SwiftUI
struct Search: View {
let sf: [SF] = Bundle.main.decode("sf.json")
@State private var searchText: String = ""
var body: some View {
NavigationView{
Form {
Section(header: Text("Search bar")){
TextField("Search", text: $searchText)
.padding(7)
.background(Color(.systemGray6))
.cornerRadius(8)
}
Section(){
List{
ForEach(sf) { item in
Text(item.title)
}
}
}
}
.navigationTitle("SF")
}
}
}
struct SF: Codable, Identifiable {
var id: String
var title: String
var items: [String]
}
extension Bundle {
func decode<T: Codable>(_ file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failed to locate \(file) in bundle.")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(file) from bundle.")
}
let decoder = JSONDecoder()
guard let loaded = try? decoder.decode(T.self, from: data) else {
fatalError("Failed to decode \(file) from bundle.")
}
return loaded
}
}
Here is the JSON file
[
{
"id": "all"
"title": "All",
"items": [
"square.and.arrow.up",
"square.and.arrow.up.fill",
"square.and.arrow.down"
]
}
]
Thank you
Hello
How di i fix the error at line 16: I
nstance member 'deci' cannot be used on type 'BMIView'; did you mean to use a value of this type instead?
import SwiftUI
struct BMIView: View {
@State var deci = "3"
var numberFormatter: NumberFormatter = {
let nf = NumberFormatter()
nf.locale = Locale.current
nf.numberStyle = .decimal
nf.maximumFractionDigits = Int(deci) ?? 0
return nf
}()
@State private var height = ""
@State private var weight = ""
@Environment(\.presentationMode) var presentationMode
var inputAfterConvertions: Double {
//Use NumberFormatter to read numeric values
let hh = numberFormatter.number(from: height)?.doubleValue ?? 0 //<-
let ww = numberFormatter.number(from: weight)?.doubleValue ?? 0 //<-
var ris: Double = 0
if hh > 0 && ww > 0{
ris = (ww / (hh * hh)) * 10000
return ris
}
return 0
}
var body: some View {
NavigationView{
Form{
Section(header: Text("Enter your height in cm")){
TextField("Input",text: $height)
.keyboardType(.decimalPad)
}
Section(header: Text("Enter your Weight in kg")){
TextField("Input",text: $weight)
.keyboardType(.decimalPad)
}
Section(header: Text("Check result")){
Text("\(inputAfterConvertions as NSNumber, formatter: numberFormatter)") //<-
}
}
.navigationTitle("BMI")
}
}
}
Thank you
Hello
I don't know why but when I put a List before my ForEach loop, all the text disappears
Code:
//
import SwiftUI
struct SearchDetailView: View {
var sf: SF
var body: some View {
ScrollView{
ForEach(sf.items, id: \.self) { item in
HStack{
Image(systemName: item)
Text(item)
}
}
.navigationTitle(sf.title)
}
}
}
Thank you for your time
Hello
I don't get any error when I fetch data but when I run I don't see any data
Thank you
import SwiftUI
import Combine
struct ContentView: View {
		@ObservedObject var networkController = NetworkController()
		@State var search: String = ""
		var body: some View {
				NavigationView{
						Form{
								Section(){
										TextField("Search", text: $search)
								}
								Section(){
										List(networkController.users.filter {
														$0.state.contains(search) }
												 , id: \.state){ user in
												Text(user.state)
										}
								}
						}
						.navigationTitle("API")
				}
		}
}
class NetworkController: ObservableObject {
		private var can: AnyCancellable?
		
		let url = URL(string: "https://api.covidtracking.com/v1/states/current.json")!
		@Published var users = [User(state: "")]
		
		init() {
				self.can = URLSession.shared.dataTaskPublisher(for: url)
						.map { $0.data }
						.decode(type: [User].self, decoder: JSONDecoder())
						.replaceError(with: [])
						.eraseToAnyPublisher()
						.receive(on: DispatchQueue.main)
						.sink(receiveValue: { users in
								self.users	= users
						})
		}
		
}
struct User: Decodable {
		var state: String
}
Hello
When I tap on my TextField more than 2/4 times the app crashes
Before that I get these errors:
2020-12-29 11:28:10.265525+0100 Nums[1670:295112] Can't find keyplane that supports type 4 for keyboard iPhone-PortraitChoco-NumberPad; using 25889PortraitChocoiPhone-Simple-PadDefault
2020-12-29 11:28:18.778004+0100 Nums[1670:295112] Can't find keyplane that supports type 4 for keyboard iPhone-PortraitChoco-NumberPad; using 25889PortraitChocoiPhone-Simple-PadDefault
2020-12-29 11:28:22.268833+0100 Nums[1670:295112] Can't find keyplane that supports type 4 for keyboard iPhone-PortraitChoco-NumberPad; using 25889PortraitChocoiPhone-Simple-Pad_Default
Then after 2/4 four times tapping on the TextField the app crashes and I get this error
2020-12-29 11:28:22.419634+0100 Nums[1670:295112] [error] precondition failure: attribute being read has no value: 768444
AttributeGraph precondition failure: attribute being read has no value: 768444.
(lldb)
Here is the TextField:
GroupBox {
						HStack {
							 TextField("Have a goal?", text: $saveGoal.bound)
									 .keyboardType(.numberPad)
									Spacer()
						Button(action: {
						UserDefaults.standard.set(self.saveGoal, forKey: "Save")																		UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
																}) {		
																		Text("Save")
																}
												}
										}.padding(.top).padding(.trailing).padding(.leading)
Thank you for your time
Hello
Is there a way to dismiss a decimal Keyboard by tapping (anywhere) on the screen (without putting .onTapGesture {hideKeyboard()} on the NavigationView)
Thank you
Hello
I'm using Measurement(...) to convert watts to femtowatts, but if I convert 1 watts to femtowatts I get 999999999999999.9 instead of 1e+15, I have no idea on how to fix it, any help or ideas, here is the code
:
import SwiftUI
struct PowerView: View {
		
		@State private var inputValue = ""
		
		 let inputUnits = [
				"watts",
				"femtowatts"
		]
		let outputUnits = [
				"watts",
				"femtowatts"
	 ]
		@State private var inputUnitValue = 0
		
		@State private var outputUnitValue = 1
		
		var after: String{
				var input = Measurement(value: 0, unit: UnitPower.watts)
				var output: String = ""
				
				switch inputUnits[inputUnitValue] {
				case "watts": input = Measurement(value: Double(inputValue) ?? 0, unit: UnitPower.watts)
				case "femtowatts": input = Measurement(value: Double(inputValue) ?? 0, unit: UnitPower.femtowatts)
				default: input = Measurement(value: Double(inputValue) ?? 0, unit: UnitPower.watts)
				}
				switch outputUnits[outputUnitValue] {
				case "watts": output = String(describing: input.converted(to: UnitPower.watts))
				case "femtowatts": output = String(describing: input.converted(to: UnitPower.femtowatts))
				default: output = String(describing: input.converted(to: UnitPower.watts))
						
				}
						
				return output
		}
		
				
		var body: some View {
				NavigationView{
						Form{
								Section(header: Text("Enter your Input value")){
												TextField("Have a goal?", text: $inputValue)
								}
								
								Section(header: Text("Input")){
										Picker("Input values", selection: $inputUnitValue){						 	 ForEach(0..<inputUnits.count){ item in
														Text(inputUnits[item])
												}
										}
								}
								
								Section(header: Text("Output")){
										Picker("Output values", selection: $outputUnitValue){
												ForEach(0..<outputUnits.count){ item in
														Text(outputUnits[item])
												}
										}
								}
								
								Section(header: Text("Check your Output value")){
										Text("\(after)")
								}
								
						}
						.navigationBarTitle("Pressure")
				}
		}
		
}
Thank you for your time
(Is there a way to use NumberFormatter with the computed String)