Post not yet marked as solved
Recently, I found that our application can only run in the background for a short time and then gets interrupted by the system, even after enabling Always Allow Location and Background Running Permissions. This has caused me a lot of frustration because I need this application to run in the background constantly to track my location and other information.
Before version 16.4, this application could run in the background for a long time, even exceeding 24 hours. However, in the 16.4 test version, the background running time is limited to no more than 10 minutes, which makes it impossible for the software to run properly in the background.
Post not yet marked as solved
I would like to register a complaint here about background location functionality (or rather lack thereof) on Apple.
My app has a very attractive user case, and we are looking to design in a sustainable way which gives the user a clear choice between a degree of battery usage and the benefits of background location tracking in performing one of the key benefits that the app is designed for. We can provide a very good product with what we believe is a very sustainable level of battery use given the benefits of the function (maybe 0.5 - 1 pct per hour when moving), but in any case we clearly present the cost benefit to the user. IT SHOULD BE THEIR CHOICE.
It does not appear that Apple allow such solutions to exist.
My complaints are as follows:
a) Apple's machine learning has a mind of its own and will suddenly render null and void a background task which was running perfectly prior to that. Nowhere do Apple document the rules of the game... this can lead to literally hundreds of thousands and years of wasted development time trying to guess what works. Should Apple not clearly lay this out in documentation? For year developers have been trying to second guess how the system works.
b) Apple's assumption is that apps used infrequently have no value. That is simply not the case. Our app is about High Quality/Low Quantity... and the high quality delivered by our background services arguably is of much higher value than the low quality pulp encouraged by the most popular regular use social media apps.
c) If GPS is a battery intensive resource, why is there not one pooled resource on a phone which then shares with apps which have the permission the relevant information? [Whilst this feature is on android phones] google very accurately tracks on android devices all background movement with sustainable battery usage.
The level of detail here is higher than we require for our purposes. Clearly therefore there are solutions that work. However Apple and Google for whatever reason have not made this available to Apps. This comes at a massive cost to the consumer who misses out on a whole family of Applications which could be of high value to them. Our App, I know I am biased, has life changing potential.
If anybody can tell me of any way that background location can be unbreakable tracked in a battery sustainable way then do please share with me. I am looking for something which reliably gets an accurate location when stationary... we thought that this could be time driven: ie every 5-10 minutes after momvement, or after the user has moved say 200 yds.
Many thanks, Angus
Post not yet marked as solved
After following along with the documentation and WWDC22 video on using the new SwiftUI Background Tasks API. My application was successfully updating in the background, then I ran into an issue where the data won't update resulting in a progress view showing and no new data being fetched but will eventually correct itself which doesn't seem right. See below screenshots below.
Data is nil at 9:13pm
Corrected itself at 9:34pm
struct DemoApp: App {
@StateObject var viewModel = ViewModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(viewModel)
}
.backgroundTask(.appRefresh("myapprefresh")) {
await viewModel.fetchData()
}
}
}
class ViewModel: ObservableObject {
@Published var pokemon = PokeAPI(name: "", sprites: Sprites(frontDefault: ""))
func fetchData() async {
URLSession.shared.dataTaskPublisher(for: request)
.map{ $0.data }
.decode(type: PokeAPI.self, decoder: JSONDecoder())
.replaceError(with: PokeAPI(name: "", sprites: Sprites(frontDefault: "")))
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {_ in
}, receiveValue: { value in
self.pokemon = value
}).store(in: &cancellables)
}
}
Post not yet marked as solved
I'm almost certain the answer is YES because of this doc: https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/about_the_background_execution_sequence.
however, the screenshot in the article shows that the Background Modes only contains Background fetch, not Background processing, this is the situation before iOS 13, so I guess this screenshot (or this article) is a little out of date.
So can anyone help me to confirm that whether application:didFinishLaunchingWithOptions will be executed during a BGAppRefreshTask after the app is terminated?
Post not yet marked as solved
I am developing an application to scan the BLE devices and its working fine in foreground mode.
But it's needed to work in background mode as well.
Now I made the scheduled work and its only fired one time.
I need to fire continuously every 15mins and scan the devices.
How can I implement this feature?
Will be any source link or reference documents?
Thanks.
Post not yet marked as solved
I want to implement a feature that keeps scanning for Bluetooth while the app is in the background and the iPhone is in a non-operational state. Is there a way to scan for Bluetooth when the app is in the background? I am going to use BLE for developing a smart door lock app.
Post not yet marked as solved
Hi Team
I am facing a problem when I put my app in background and after a while due to CPU over usage it gets terminated.
Now I am managing a web page session in another tab which is quite important for us and we want that if app got terminated by OS then we redirect user to the previous activity he is having but for that I need to render a flag, but here I am facing problem because applicationWillTerminate function is not letting me change any value in NSUserDefaults and I am stuck at this point.
So if anyone has any idea how can we achieve it, it would be a good help for us.
Thanks & Regards
Mayank Sharma
Post not yet marked as solved
Hello, I have an application which displays the APOD (Astronomy Photo Of The Day), using NASA's API (this includes displaying the actual picture, description, author and title). I am learning how to implement Background App Refresh using the BackgroundTasks framework and simulating it using Apple's code for simulating Background App Refresh
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]
My Background App Refresh Task, updates the UI from the main View Controller (including the outlets), by fetching this information from the APOD API by NASA. However, when I simulate the Background App Refresh Task, the app crashes with the following message:
2023-03-01 16:43:08.394054-0600 SpacePhoto[9069:858984] SpacePhoto/ViewController.swift:73: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
This message is pointed out in the following code line:
descriptionLabelOutlet.text = photoInfo.description
From what I have read, when my Background App Refresh Task is executed, the @IBOutlets are deallocated from memory and the View Controller references for such outlets are not being read, thus leading to the application crash.
Here is the code from my View Controller:
import UIKit
@MainActor
class ViewController: UIViewController, UIImagePickerControllerDelegate {
static var shared = ViewController()
var spacePhotoInfoTask: Task<Void, Never>? = nil
deinit { spacePhotoInfoTask?.cancel()}
// Access network request
let photoInfoController = PhotoInfoController()
...
@IBOutlet var descriptionLabelOutlet: UILabel!
...
// Send network request and assign the resulting String to the descriptionLabelOutlet
func updateInterface() {
spacePhotoInfoTask?.cancel()
spacePhotoInfoTask = Task {
do {
let photoInfo = try await photoInfoController.fetchPhotoInfo()
self.descriptionLabelOutlet.text = photoInfo.description
} catch {
print("Could not update extra Label with \(error)")
}
}
}
...
}
Here is the code corresponding to the AppDelegate:
import UIKit
import BackgroundTasks
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
BGTaskScheduler.shared.register(forTaskWithIdentifier: "Space", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
scheduleAppRefresh()
print("Scheduled")
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "Space")
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
// The performApplicationUpdates method, performs the UI update (method declaration included below)
let operations = Operations.performApplicationUpdates()
let lastOpertation = operations.last!
task.expirationHandler = {
queue.cancelAllOperations()
}
lastOpertation.completionBlock = {
task.setTaskCompleted(success: !lastOpertation.isCancelled)
}
queue.addOperations(operations, waitUntilFinished: false)
print("Handled App Refresh")
}
}
And finally, here is the declaration for the performApplicationUpdates method, which calls the updateInterface() method from the main View Controller:
import Foundation
import UIKit
@available(iOS 16.0, *)
struct Operations {
static func performApplicationUpdates() -> [Operation] {
let refreshHomeViewController = RefreshViewControllerInterface()
return [refreshHomeViewController]
}
}
@available(iOS 16.0, *)
class RefreshViewControllerInterface: Operation {
override func main() {
DispatchQueue.main.async {
ViewController.shared.updateInterface()
}
}
}
How can I fix this? Is there a way to update the UI and my @IBOutlets' information using Background App Refresh?
Thank you!
Hello,
I have an application which displays the APOD (Astronomy Photo Of The Day), using NASA's API (this includes displaying the actual picture, description, author and title).
I am learning how to implement Background App Refresh using the BackgroundTasks framework and simulating it using Apple's code for simulating Background App Refresh
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]
My Background App Refresh Task, updates the UI from the main View Controller (including the outlets), by fetching this information from the APOD API by NASA. However, when I simulate the Background App Refresh Task, the app crashes with the following message:
2023-03-01 16:43:08.394054-0600 SpacePhoto[9069:858984] SpacePhoto/ViewController.swift:73: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
This message is pointed out in the following code line:
descriptionLabelOutlet.text = photoInfo.description
From what I have read, when my Background App Refresh Task is executed, the @IBOutlets are deallocated from memory and the View Controller references for such outlets are not being read, thus leading to the application crash.
How can I fix this? Is there a way to update the UI and my @IBOutlets' information using Background App Refresh?
Thank you.
Post not yet marked as solved
Hello everyone!
I need to run a function every X time, and after searching all over the web, I realized that the best way for that is using the Background Tasks framework.
Problem is, although I manage to successfully register and submit a Task, it never happens.
About the code, I register the tasks when the app is launched:
@main
struct PersonalEnciclopediaApp: App {
init() {
NotificationManager.shared.requestAuthorization()
BackgroundTaskManager.shared.register()
}
var body: some Scene {
WindowGroup {
BackgroundTasks()
}
}
}
The above code requests notification authorization (which is working fine), and fires the register function:
func register() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: identifier, using: .main) { task in
self.handleTask(task)
}
scheduleAppRefresh()
}
The code above registers my task, schedules a new Task with the method scheduleAppRefresh() and, for what I understood, tells the system that the functions that needs to be called when the task starts is handleTask(), which is:
func handleTask(_ task: BGTask) {
scheduleAppRefresh()
show(message: "handleTask: \(task.identifier)")
let request = performRequest { error in
task.setTaskCompleted(success: error == nil)
}
task.expirationHandler = {
task.setTaskCompleted(success: false)
request.cancel()
}
}
Again, for what I understood, the handleTask method calls the method performRequest, which is:
func performRequest(completion: @escaping (Error?) -> Void) -> URLSessionTask {
show(message: "starting performRequest")
let url = URL(string: "https://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) { _, _, error in
print("finished request")
completion(error)
}
task.resume()
return task
}
And just so that this post is complete, the show method's responsability is just showing a notification:
func show(message: String) {
let content = UNMutableNotificationContent()
content.title = "AppRefresh task"
content.body = message
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error {
print("error \(error.localizedDescription)")
}
}
}
Here is the complete class (just in case its needed):
import Foundation
import BackgroundTasks
import UserNotifications
extension BackgroundTaskManager {
static let shared = BackgroundTaskManager()
private init() { }
let identifier = "com.hsilvgar.notifications"
func register() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: identifier, using: .main, launchHandler: handleTask(_:))
scheduleAppRefresh()
}
func handleTask(_ task: BGTask) {
scheduleAppRefresh()
show(message: "handleTask: \(task.identifier)")
let request = performRequest { error in
task.setTaskCompleted(success: error == nil)
}
task.expirationHandler = {
task.setTaskCompleted(success: false)
request.cancel()
}
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: self.identifier)
var message = "Scheduled"
do {
try BGTaskScheduler.shared.submit(request)
} catch BGTaskScheduler.Error.notPermitted {
message = "BGTaskScheduler.shared.submit notPermitted"
} catch BGTaskScheduler.Error.tooManyPendingTaskRequests {
message = "BGTaskScheduler.shared.submit tooManyPendingTaskRequests"
} catch BGTaskScheduler.Error.unavailable {
message = "BGTaskScheduler.shared.submit unavailable"
} catch {
message = "BGTaskScheduler.shared.submit \(error.localizedDescription)"
}
show(message: "scheduleAppRefresh: \(message)")
}
func show(message: String) {
let content = UNMutableNotificationContent()
content.title = "AppRefresh task"
content.body = message
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error {
print("error \(error.localizedDescription)")
}
}
}
func performRequest(completion: @escaping (Error?) -> Void) -> URLSessionTask {
show(message: "starting performRequest")
let url = URL(string: "https://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) { _, _, error in
print("finished request")
completion(error)
}
task.resume()
return task
}
}
So the problem is, I get the "Scheduled" notification, but I never get the notification from within performRequest(), which would tell me the task was processed.
PS:
1- I have already registered "Background Modes" with "Background fetch" and "Background processing" on my App's Signing & Capabilities
2- I have already registered the Identifier on Info.plist (in BGTaskSchedulerPermittedIdentifiers)
Here is my info.plist (if needed)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.hsilvgar.notifications</string>
</array>
<key>UIApplicationExitsOnSuspend</key>
<false/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
</array>
</dict>
</plist>
Does anyone know what am I missing, or what is wrong?
Post not yet marked as solved
When app goes to background I wanted to connect bluetooth device with Core Bluetooth, With BGProcessingTaskI was able to perform background task(it executes after 15 min keeping app in background) but connection is not happening it didn't trigger CBCentralManagerDelegatemethods.
Here is what I've tried.
I have enabled necessary Background Modes in Capabilities.
Added required things in info.plist.
When app launches I'm registering BGProcessingTask as below.
When app goes to background will submit request and after 15 min it starts executing task handleBackgroundSync function.
In the handleBackgroundSync function as usual I'm trying to connect bluetooth device with Core Bluetooth. With breakpoint can debug upto scanning but CBCentralManagerDelegate delegates methods are not triggering and when I come to foreground then it triggers.
Is there a way to establish bluetooth connection with the BGProcessingTask can someone please suggest ?
When I submit a request for a background refresh through BGTaskScheduler, how likely is it that iOS will execute the task at the time I request?
I know that with the pre-iOS 13 way of doing this, iOS didn't really guarantee any particular schedule or frequency except that it it would try to execute the task when it wasn't busy. I don't see any language in BGTaskScheduler that talks about this. The only clue is that the field specifying the time is called "earliestBeginDate" which suggests that iOS might execute it later than that date.
If I submit a BGProcessingTaskRequest instead of a BGAppRefreshTaskRequest, does this change the behavior?
I'd like to know this so that I can tell my users what to expect.
Thanks,
Frank
Post not yet marked as solved
Hi guys, I got one issue about sending data with interval 1000 seconds to the server, while the app has been killed by user. I found the relevant document about app in background mode. https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html but I checked the document, it seems there is no way to use NSTimer inside the block of beginBackgroundTaskWithName... function. NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: #selector(AppDelegate.handleTimer), userInfo: nil, repeats: true) Question: How to consistently send data to server with interval time while app has been terminated? Thank you, e
Post not yet marked as solved
I'm trying to do some network requests in a BGAppRefreshTask's lanchHandler, but I'm getting some crashes. It is hard to recreate the crash on my now device. The crash count / DAU is about 1% according to log, by the way, my app is running under an enterprise account.
The last lines of the crash log is like:
0 CoreFoundation 0x0000000196475e48 __exceptionPreprocess + 164
1 libobjc.A.dylib 0x000000018f7478d8 objc_exception_throw + 60
2 Foundation 0x0000000190d3694c _userInfoForFileAndLine + 0
3 BackgroundTasks 0x00000001feb7fcfc -[BGTaskScheduler _callRegisteredHandlersForActivities:] + 528
4 BackgroundTasks 0x00000001feb7d184 -[BGTaskScheduler _handleAppLaunch] + 324
5 BackgroundTasks 0x00000001feb7cfdc __50+[BGTaskScheduler _applicationDidFinishLaunching:]_block_invoke + 52
...
It also shows: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No launch handler registered for task with identifier com.my.identifier’
I believe I have done all the necessary steps(I setup according to the demo: https://developer.apple.com/documentation/backgroundtasks/refreshing_and_maintaining_your_app_using_background_tasks) to setup BGTask, I call BGTaskScheduler’s register method in the app's didFinishLaunchingWithOptions, and call BGTaskScheduler’s submit method in the app's applicationDidEnterBackground method, I also call BGTaskScheduler’s submit method in the BGTask's launchHandler(because I want to trigger the task more than one time after into background).
Since the error info is No launch handler registered, but I actually call register in the didFinishLaunchingWithOptions, is it possible that the register method failed for other some reason except for not adding the identifier in the info.plist?
Does anyone know why the launchHandler is not registered? What do I miss?
Thank you all in advance
Post not yet marked as solved
I am looking to automatically fetch some new (and large) content in the background while the app is closed. The content that needs to be downloaded is user specified, and as such doesn't need to run on install or update, but only periodically to see if the content has been updated.
The app is a mac app, and I wanted to know if Background Assets is a good choice for this, as the app may not always be running, and I'd like for the user's content to be updated seemingly when they open the app.
If this is the right course of action, what is a recommended way of implementing this?
I was thinking of scheduling a request to check for updated assets in BADownloaderExtension.download() and then checking in
BADownloaderExtension.backgroundDownload(_:finishedWithFileURL:) if are new content, and then schedule the download of new content or if it is new content then installing it appropriately from there.
Thank you
- Bastian
Post not yet marked as solved
For our taxi app, we need to continuously send the driver's location to the server every 5 seconds for accurate tracking. If the user switches to another app or puts the app in the background, can the location updates continue? Also, what happens if the screen is locked?
We haven't implemented it yet but if IOS does not support websockets in the background we might need to rewrite the existing backend.
Post not yet marked as solved
I’m working on an independent watchOS app which is primarily designed to to collect and periodically send location updates to a server. The UI features a toggle that allows the user to turn this capability on or off at their discretion. The typical use case scenario would be for the user to turn the toggle on in the morning, put the app in the background and then go about their day.
Given the limitations and restrictions regarding background execution on watchOS, in an ideal situation, I would be able to upload the stored location updates about every 15-20 minutes. With an active complication on the watch face, it’s my understanding that this should be possible. I’ve implemented background app refresh and indeed, I do see this reliably being triggered every 15-20 minutes or so.
In my handle(_:) method, I process the WKApplicationRefreshBackgroundTask like this:
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
backgroundTasks.forEach { task in
switch task {
case let appRefreshBackgroundTask as WKApplicationRefreshBackgroundTask:
// start background URL session to upload data; watchOS will perform the request in a separate process so that it will continue to run even if our app gets
// terminated; when the system is done transferring data, it will call this method again and backgroundTasks will contain an instance of
// WKURLSessionRefreshBackgroundTask which will be processed below
startBackgroundURLSessionUploadTask()
scheduleNextBackgroundAppRefresh()
appRefreshBackgroundTask.setTaskCompletedWithSnapshot(false)
case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
// add urlSessionTask to the pendingURLSessionRefreshBackgroundTasks array so we keep a reference to it; when the system completes the upload and
// informs us via a URL session delegate method callback, then we will retrieve urlSessionTask from the pendingURLSessionRefreshBackgroundTasks array
// and call .setTaskCompletedWithSnapshot(_:) on it
pendingURLSessionRefreshBackgroundTasks.append(urlSessionTask)
// create another background URL session using the background task’s sessionIdentifier and specify our extension as the session’s delegate; using the same
// identifier to create a second URL session allows the system to connect the session to the upload that it performed for us in another process
let configuration = URLSessionConfiguration.background(withIdentifier: urlSessionTask.sessionIdentifier)
let _ = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
default:
task.setTaskCompletedWithSnapshot(false)
}
}
}
And here is how I'm creating and starting the background URL session upload task:
func startBackgroundURLSessionUploadTask() {
// 1. check to see that we have locations to report; otherwise, just return
// 2. serialize the locations into a temporary file
// 3. create the background upload task
let configuration = URLSessionConfiguration.background(withIdentifier: Constants.backgroundUploadIdentifier)
configuration.isDiscretionary = false
configuration.sessionSendsLaunchEvents = true
let backgroundUrlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let request: URLRequest = createURLRequest() // this is a POST request
let backgroundUrlSessionUploadTask = backgroundUrlSession.uploadTask(with: request, fromFile: tempFileUrl)
backgroundUrlSessionUploadTask.countOfBytesClientExpectsToSend = Int64(serializedData.count) // on average, this is ~1.5 KB
backgroundUrlSessionUploadTask.countOfBytesClientExpectsToReceive = Int64(50) // approximate size of server response
backgroundUrlSessionUploadTask.resume()
}
Note that I'm not setting the .earliestBeginDate property on the backgroundUrlSessionUploadTask because I'd like the upload to start as soon as possible without any delay. Also, this same class (my WatchKit application delegate) conforms to URLSessionTaskDelegate and I have implemented urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:) and urlSession(_:task:didCompleteWithError:).
In my testing (on an actual Apple Watch Ultra running watchOS 9.3.1), I've observed that when the system performs the background app refresh, I always receive a callback to myhandle(_:) method. But when I start the background URL session upload task (in startBackgroundURLSessionUploadTask()), I was expecting that when the upload completes, I'd receive another call to myhandle(_:) method with an instance of WKURLSessionRefreshBackgroundTask but this doesn't seem to happen consistently. Sometimes I do see it but other times, I don't and when I don't, the data doesn't seem to be getting uploaded.
On a side note, most of the time, startBackgroundURLSessionUploadTask() gets called as a result of my code handling a background app refresh task. But when the user turns off the toggle in the UI and I stop the location updates, I need to report any stored locations at that time and so I call startBackgroundURLSessionUploadTask() to do that. In that specific case, the upload seems to work 100% of the time but I definitely don't see a callback to my handle(_:) method when this occurs.
Am I wrong in expecting that I should always be getting a callback to handle(_:) when a background URL session upload task completes? If so, under what circumstances should this occur? Thanks very much!
Post not yet marked as solved
My Electron app is no longer able to send emails locally to my SMTP server at port 1025 (I'm using Mailhog). I'm getting a timeout all of a sudden, the code wasn't changed at all. The only difference is that I installed the newest update of macOS Venture on my Mac Mini yesterday.
I've followed the instructions in https://kinsta.com/blog/mailhog/ to reinstall Mailhog via Brew, restarted the service but when I come to the example given to test mailhog it fails with:
-bash: mhsendmail: command not found
I've noticed that Apple is now showing a popup for “Background Items Added”. This is a new feature they added, might be it’s the culprit though it’s turned on:
Can this be the cause why the SMTP is timing out?
Everything was working fine for years until this update yesterday.
Thanks in advance!
Post not yet marked as solved
I am new to Apple app development, so I am still learning.
My first application is a basic countdown timer.
Xcode 14.2 and Swift / UIKit
Target iPhone 15.0 and higher
My goal is the timer will count down and alert the user with a tone/vibrate when it reaches zero.
Currently I have a working app but have two challenges:
When the iPhone screen blanks, my timer stops counting down. What is the best dev approach to keep the timer counting in the background even if the screen blanks or device locks?
If I can solve #1, then I will have a second challenge to sound an alarm tone/vibrate if the counter reaches zero while the screen is blank or device is locked.
Here is the code I am using to trigger the timer:
@IBAction func clickStartPauseButton(_ sender: Any) {
{
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
...
}
And this code is doing the work to increment my counter variable:
@objc func timerAction() {
if (counter > 0) {
counter = counter - 1
} else {
timer.invalidate()
}
}
Thank you for any assistance or direction. A resource with some sample code would be much appreciated.
Post not yet marked as solved
Hi,
I have been using the BackgroundTasks API on iOS for a while, and it works great. I want to do something similar on macOS, where I can easily run some background process from my app every X minutes, even if the app is closed. My Mac app runs in the sandbox, and isn't Catalyst-based, so I can't run the UIKit 'BackgroundTasks' API, and I haven't found anything similar on macOS. Does something like that exist, that is easy to adopt?