We are using a 3rd party SDK which crashes on iOS 18 in certain scenarios. They say they need Apple to fix this bug ahead of release https://github.com/swiftlang/swift/issues/75952 but I'm skeptical since it is only a few weeks away most likely. The bug seems pretty bad so is there any chance it will be fixed before iOS 18? We aim for a same-day release so would be great to know if we need to remove the 3rd party SDK or not.
Post
Replies
Boosts
Views
Activity
I’m trying to use BGProcessingTaskRequest to fetch step data in the background and send it. However, when I combine BGProcessingTaskRequest, HKObserverQuery, and healthStore.enableBackgroundDelivery, the results sometimes return zero. When I don’t schedule the BGProcessingTaskRequest, the data retrieved using HKObserverQuery and HKSampleQueryDescriptor is correct.
// Register Smart Walking Sync Task
func registerSmartWalkingSync() {
#if !targetEnvironment(simulator)
BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTaskIdentifier.smartwalking.rawValue, using: nil) { task in
guard let task = task as? BGProcessingTask else { return }
self.handleSmartWalkingSync(task: task)
}
#endif
}
func scheduleSmartWalkingSync(in seconds: TimeInterval? = nil, at date: Date? = nil) {
let newRequest = BGProcessingTaskRequest(identifier: BGTaskIdentifier.smartwalking.rawValue)
newRequest.requiresNetworkConnectivity = true
newRequest.requiresExternalPower = false
if let seconds = seconds {
newRequest.earliestBeginDate = Date().addingTimeInterval(seconds)
} else if let date = date {
newRequest.earliestBeginDate = date
}
do {
try BGTaskScheduler.shared.submit(newRequest)
debugPrint("✅ [BGTasksManager] scheduled for Smart Walking Sync")
} catch {
FirebaseConnection.shared.recordException(error)
debugPrint("❌ [BGTasksManager] error: \(error)")
}
}
// Handle Smart Walking Sync Task
func handleSmartWalkingSync(task: BGProcessingTask) {
debugPrint("🔄 [BGTasksManager] sync \(task.identifier) sync started")
scheduleSmartWalkingSync(in: SYNC_SMARTWALKING_TIME_INTERVAL)
let queue = OperationQueue()
let operation = HealthActivitiesOperation()
operation.completionBlock = {
Task {
do {
try await operation.sync()
task.setTaskCompleted(success: !operation.isCancelled)
debugPrint("✅ [BGTasksManager] sync \(task.identifier) completed successfully")
} catch {
FirebaseConnection.shared.recordException(error)
task.setTaskCompleted(success: false)
debugPrint("❌ [BGTasksManager] sync \(task.identifier) error: \(error)")
}
}
}
task.expirationHandler = {
operation.cancel()
}
queue.addOperation(operation)
}
// MARK: - HealthKit Background Delivery
internal func enableBackgroundDeliveryForAllTypes() async throws {
for type in allTypes.filter({ type in
type != HKQuantityType(.heartRate)
}) {
try await healthStore.enableBackgroundDelivery(for: type, frequency: .daily)
}
debugPrint("✅ [HealthKitManager] Enable Background Delivery")
}
internal func observeHealthKitQuery(predicate: NSPredicate?) async throws -> Set<HKSampleType> {
let queryDescriptors: [HKQueryDescriptor] = allTypes
.map { type in
HKQueryDescriptor(sampleType: type, predicate: predicate)
}
return try await withCheckedThrowingContinuation { continuation in
var hasResumed = false
let query = HKObserverQuery(queryDescriptors: queryDescriptors) { query, updatedSampleTypes, completionHandler, error in
if hasResumed {
return
}
if let error = error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: updatedSampleTypes ?? [])
}
hasResumed = true
completionHandler()
}
healthStore.execute(query)
}
}
internal func getHealthActivity(by date: Date, predicate: NSCompoundPredicate, sampleTypes: Set<HKSampleType>) async throws -> HealthActivityData {
var data = HealthActivityData(steps: 0, calories: 0, distance: 0.0, distanceCycling: 0.0, totalDuration: 0, date: date, heartRate: nil)
for sampleType in sampleTypes {
guard let quantityType = sampleType as? HKQuantityType else {
continue
}
switch quantityType {
case HKQuantityType(.stepCount):
let stepCount = try await getDescriptor(
date: date,
type: quantityType
).result(for: healthStore)
.statistics(for: date)?.sumQuantity()?.doubleValue(for: HKUnit.count())
data.steps = stepCount ?? 0.0
// Calculate total duration using HKSampleQueryDescriptor
let totalDurationDescriptor = HKSampleQueryDescriptor(
predicates: [.quantitySample(type: quantityType, predicate: predicate)],
sortDescriptors: [SortDescriptor(\.endDate, order: .reverse)]
)
let stepSamples = try await totalDurationDescriptor.result(for: healthStore)
data.totalDuration += stepSamples
.reduce(0) { $0 + $1.endDate.timeIntervalSince($1.startDate) } / 60.0
default:
debugPrint("Unknown quantity type")
}
}
return data
}
We have been successfully using the PTT (Push-to-Talk) framework in our application since the release of iOS 17.
Audio is recorded by pressing a PTT button and speaking after the PTT framework initiates an AVAudioSession.
While the PTT framework has generally worked well since the iOS 17 release, we have received reports that, on occasion, after the app has been idle for a while ( when I have seen it my phone has been in flightmode over night), it suddenly records only silent audio. This issue does not occur every time but sporadically. For users experiencing this problem, pressing the PTT button results in no “PTT framework start sound,” and only “empty sound” is recorded. The only solution to restore audio is restarting the device. Restarting the app alone is insufficient, though leaving the PTT channel and rejoining it also resolves the issue.
I have reproduced the problem several times and observed that everything appears normal within the app. We receive an active AVAudioSession from the PTT framework, and it seems like the app is recording, but all recorded sound packets are silent.
Upon reviewing logs from the phone (via the Console app), I noticed that the app is muted when starting the recording and unmuted after stopping the recording. For example:
• Start recording ≈ 15:01:30
• Stop recording ≈ 15:01:44
• 15:01:30.124144+0100 audiomxd -CMSessionMgr- MXCoreSessionSetProperty: Session ‘sid:0xa80037, AppName(2717), ‘prim’’ isRecordingMuted updated to ‘1’
• 15:01:44.384208+0100 audiomxd -CMSessionMgr- MXCoreSessionSetProperty: Session ‘sid:0xa80037, AppName(2717), ‘prim’’ isRecordingMuted updated to ‘0’
When the system functions normally, the isRecordingMuted flag toggles between 0 and 1, but remains at 0 (non-muted) during recording. After stopping the recording, this state does not change anymore, unlike in the error state.
There is no difference in behavior whether the app is in the foreground or background when starting the transmission, or whether the PTT framework’s “Talk” button is used once the device enters the “error state.”
I have filed a bug report with logs provided on 28 November 2023 that is still open but no feedback.
We now have customers that are reporting this issue again on 17.5.1 and its starting to be a big issue.
Anyone else that have similar problems ?
I have a model "Objetive" with recursive iteration. In the user interface I can see all the Items, as expected, and I can expands all those that have children. However, I encounter an error when attempting to compact anyone with children that I have previously expanded, But only when I'm using Mac OS 15.1 On iOS 18.1 Works perfectly.
The error happens in List, Outlinegroup or Table.
struct ObjectiveTable: View{
@Query(filter: #Predicate<Objective>{$0.parent == nil}) var all : [Objective]
@State var selected : Objective?
var body: some View{
VStack{
List(all ,children: \Objective.sonsNIL){ line in
Text(line.name)
}
}
}
}
@Model
final class Objective{
@Attribute(.unique)
var id = UUID()
var name: String
var parent: Objective? = nil
@Relationship(deleteRule: .cascade, inverse: \Objective.parent)
var sons: [Objective] = []
var sonsNIL: [Objective]?{
get{
if sons.count < 1{
return nil
} else{
return sons
}
}
}
...
ERROR
Row index -1 out of row range (numberOfRows: 14) for <SwiftUI.SwiftUIOutlineListView: 0x129852200>
(
0 CoreFoundation 0x000000018c834ec0 __exceptionPreprocess + 176
1 libobjc.A.dylib 0x000000018c31acd8 objc_exception_throw + 88
2 AppKit 0x00000001903eb304 -[NSTableRowData availableRowViewWhileUpdatingAtRow:] + 0
3 SwiftUI 0x00000001bb365224 $s7SwiftUI0A17UIOutlineListViewC11removeItems2at8inParent13withAnimationy10Foundation8IndexSetV_ypSgSo07NSTableeL7OptionsVtF + 1388
4 SwiftUI 0x00000001bb3656f8 $s7SwiftUI0A17UIOutlineListViewC11removeItems2at8inParent13withAnimationy10Foundation8IndexSetV_ypSgSo07NSTableeL7OptionsVtFTo + 252
5 CoreFoundation 0x000000018c7a28b4 invoking + 148
6 CoreFoundation 0x000000018c7a272c -[NSInvocation invoke] + 428
7 CoreFoundation 0x000000018c7d7958 -[NSInvocation invokeWithTarget:] + 64
8 AppKit 0x000000019052a110 -[NSObjectAnimator forwardInvocation:] + 1512
9 CoreFoundation 0x000000018c7a0ee4 forwarding + 964
10 CoreFoundation 0x000000018c7a0a60 CF_forwarding_prep_0 + 96
11 SwiftUI 0x00000001bb37e458 $s7SwiftUI22OutlineListCoordinatorC19recursivelyDiffRows_4with2by9expandAllyAA0a9UIOutlineD4ViewC_AA0dC4ItemCAA0nD4TreeVAA14ExpansionStateOtF + 37012
12 SwiftUI 0x00000001bb3802b8 $s7SwiftUI22OutlineListCoordinatorC19recursivelyDiffRows_4with2by9expandAllyAA0a9UIOutlineD4ViewC_AA0dC4ItemCAA0nD4TreeVAA14ExpansionStateOtF + 44788
13 SwiftUI 0x00000001bb37538c $s7SwiftUI22OutlineListCoordinatorC8diffRows2of2toyAA0a9UIOutlineD4ViewC_AA0kD4TreeVtF + 120
14 SwiftUI 0x00000001bb36f3d4 $s7SwiftUI22OutlineListCoordinatorC6update4diff04viewD4Tree18idSelectionChanged010navigationk4SeedL0011templateRowL011transactionySb_AA04ViewdI0VS3bAA11TransactionVtFyycfU_yyXEfU + 220
15 SwiftUI 0x00000001bb369044 $s7SwiftUI22OutlineListCoordinatorC24withSelectionUpdateGuard33_BE7B171B0BEE2A9E27ED12968C3771F8LLyySS_yyXEtF + 1320
16 SwiftUI 0x00000001bb36f2d4 $s7SwiftUI22OutlineListCoordinatorC6update4diff04viewD4Tree18idSelectionChanged010navigationk4SeedL0011templateRowL011transactionySb_AA04ViewdI0VS3bAA11TransactionVtFyycfU + 708
17 SwiftUICore 0x00000002277cb578 $sIeg_ytIegr_TRTA + 28
18 SwiftUICore 0x0000000227a6d2b8 $s7SwiftUI6UpdateO15dispatchActionsyyFZ + 1236
19 SwiftUICore 0x0000000227a6c79c $s7SwiftUI6UpdateO3endyyFZ + 212
20 SwiftUICore 0x0000000227f6061c $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_Tf4ddd_n + 176
21 CoreFoundation 0x000000018c7c17a8 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 36
22 CoreFoundation 0x000000018c7c1694 __CFRunLoopDoObservers + 552
23 CoreFoundation 0x000000018c7c0380 CFRunLoopRunSpecific + 648
24 HIToolbox 0x0000000197c000cc RunCurrentEventLoopInMode + 292
25 HIToolbox 0x0000000197c05d1c ReceiveNextEventCommon + 220
26 HIToolbox 0x0000000197c06020 _BlockUntilNextEventMatchingListInModeWithFilter + 76
27 AppKit 0x0000000190303650 _DPSNextEvent + 660
28 AppKit 0x0000000190c2a408 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 688
29 AppKit 0x00000001902f675c -[NSApplication run] + 480
30 AppKit 0x00000001902cd02c NSApplicationMain + 888
31 SwiftUI 0x00000001ba77045c $s7SwiftUI6runAppys5NeverOSo21NSApplicationDelegate_So11NSResponderCXcFTf4e_nAA07TestingdG0C_Tg5Tm + 160
32 SwiftUI 0x00000001babf4854 $s7SwiftUI6runAppys5NeverOxAA0D0RzlF + 84
33 SwiftUI 0x00000001baf04134 $s7SwiftUI3AppPAAE4mainyyFZ + 224
34 Marlo SystemManagement.debug.dylib 0x0000000100ce6130 $s22Marlo_SystemManagement0a1_bC3AppV5$mainyyFZ + 40
35 Marlo SystemManagement.debug.dylib 0x0000000100ce61fc __debug_main_executable_dylib_entry_point + 12
36 dyld 0x000000018c358274 start + 2840
)
FAULT: NSTableViewException: Row index -1 out of row range (numberOfRows: 14) for <SwiftUI.SwiftUIOutlineListView: 0x129852200>; (user info absent)
OK, so I'm trying to share some utils classes for logging. The problem is a use-case where I want to create a debug notification.
However, inside the app, I want to show a popup instead if the app is showing, but I can't share that code because it uses UIApplication.shared.ApplicationState.
I've tried gating it off with all sorts of methods, @available etc. but I get compilation error "unavailable for application extensions"
Example of me trying:
static func doNotification(_ header: String, message: String) {
//so I'm trying to gate off the code that only can be called in an extension , and in addition I have @available below
if(isAppExtension()){
doNotificationFromExtension(header, message: message)
}else{
doNotificationFromApp(header, message: message)
}
}
@available(iOSApplicationExtension, unavailable)
static func doNotificationFromApp(_ header: String, message: String) {
let state = UIApplication.shared.applicationState
if state != .active {
//my dialog handler in-app popup
}else{
NotifUtils.createLocalNotification(message, header: header, category: NOTIFICATION_CATEGORY_DEBUG, playSound: false)
}
}
//here I know that I'm in an extension, so app isn't showing - always local notification
static func doNotificationFromExtension(_ header: String, message: String) {
NotifUtils.createLocalNotification(message, header: header, category: NOTIFICATION_CATEGORY_DEBUG, playSound: false)
}
static func isAppExtension() -> Bool {
return Bundle.main.executablePath?.contains(".appex/") ?? false
}
Is there any way to share the code like this? The reason I want to do this is because I have various live activity code that I'd want to re-use, but this is a show.-stopper.
Hello,
I've been working on my macos app for months, today I opened XCode, and it's full of the same errors "Value of type 'URL' has no member 'url''" and "Cannot convert value of type 'Binding' to expected argument type 'CGFloat'". I didn't change ANYTHING, I didn't update nor remove anything, the 3rd party module I'm using didn't get updated, this is all out of the blue!
I tried to clean the build folder, erase the derivated data, rebuild a new project, these errors won't go away...worst part is that another of my app use the same codes and there I see the errors but the app still compiles and build!!
Can AppClip dowload from smartbanner in other browser difference Safari ?
Hello, I have a problem with the .onMove function. I believe I have set everything up properly. However, the moving does not seem to be working correctly. When I try to move the item, it is highlighted first, as it is supposed to be. Then, while I am moving it through the list, it disappears for some reason, and at the end of the move, it comes back to its initial place. (I use iOS 16.0 minimum, so I don't have to include the EditButton(). It works the same in the edit mode tho)
import SwiftUI
struct Animal: Identifiable {
var id = UUID()
var name: String
}
struct ListMove: View {
@State var animals = [Animal(name: "Dog"), Animal(name: "Cat"), Animal(name: "Cow"), Animal(name: "Goat"), Animal(name: "Chicken")]
var body: some View {
List {
ForEach(animals) { animal in
Text(animal.name)
}
.onMove(perform: move)
}
}
func move(from source: IndexSet, to destination: Int) {
animals.move(fromOffsets: source, toOffset: destination)
}
}
#Preview {
ListMove()
}
I've got a problem with compatibility with Swift6 in iOS app that I have no idea how to sort it out.
That is an extract from my main app file
@MainActor
@main struct LangpadApp: App {
...
@State private var notificationDataProvider = NotificationDataProvider()
@UIApplicationDelegateAdaptor(NotificationServiceDelegate.self) var notificationServiceDelegate
var body: some Scene {
WindowGroup {
TabView(selection: $tabSelection) {
...
}
.onChange(of: notificationDataProvider.dateId) { oldValue, newValue in
if !notificationDataProvider.dateId.isEmpty {
tabSelection = 4
}
}
}
}
init() {
notificationServiceDelegate.notificationDataProvider = notificationDataProvider
}
}
and the following code shows other classes
@MainActor
final class NotificationServiceDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate
{
var notificationDataProvider: NotificationDataProvider?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
func setDateId(dateId: String) {
if let notificationDataProvider = notificationDataProvider {
notificationDataProvider.dateId = dateId
}
}
nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
// After user pressed notification
let content = response.notification.request.content
if let dateId = content.userInfo["dateId"] as? String {
await MainActor.run {
setDateId(dateId: dateId)
}
}
}
nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
// Before notification is to be shown
return [.sound, .badge, .banner, .list]
}
}
@Observable
final public class NotificationDataProvider : Sendable {
public var dateId = ""
}
I have set Strict Concurrency Checking to 'Complete.' The issue I'm facing is related to the delegate class method, which is invoked after the user presses the notification.
Current state causes crash after pressing notification. If I remove "nonisolated" keyword it works fine but I get the following warning
Non-sendable type 'UNNotificationResponse' in parameter of the protocol requirement satisfied by main actor-isolated instance method 'userNotificationCenter(_:didReceive:)' cannot cross actor boundary; this is an error in the Swift 6 language mode
I have no idea how to make it Swift6 compatible. Does anyone have any clues?
I'm used to wait for expectations when using XCTest, but I'm completely stumped by the seemingly-absent option for expecting some parts of my code to be called in Swift Testing 🤔
Consider the following:
protocol MyAPI {
func getData() async throws -> String
}
class MockAPI: MyAPI {
let stub: () async throws -> String
init(stub: @escaping () async throws -> String = { "hello" }) {
self.stub = stub
}
func getData() async throws -> String {
try await stub()
}
}
Which is being used in my view model:
class MyViewModel: ObservableObject {
private let api: MyAPI
@Published
var data: String
init(api: MyAPI) {
self.api = api
}
func refresh() async throws {
self.data = try await api.getData()
}
}
When I wrote tests in the past, I would simply override the stub of the MockAPI implementation and fulfill an expectation in there:
class MyViewModelTests: XCTestCase {
func testModelCallsAPIOnRefresh() async throws {
let expectCallsAPI = expectation("Model should call API")
let api = MockAPI {
expectCallsAPI.fulfill()
return "hello"
}
let model = MyViewModel(api: api)
try await model.refresh()
await fulfillment(of: [expectCallsAPI], timeout: 1)
}
}
How would I go about checking that my model does indeed call the API when using Swift Testing?
Bug
When you try to extend from NSViewRepresentable but you have a class named Context swift throws a error message that doesn't help at all.
Type 'MetalViewRepresentable' does not conform to protocol 'NSViewRepresentable'
Steps to reproduce
Create a MacOS App
Copy this code
struct MetalViewRepresentable: NSViewRepresentable {
@Binding var metalView: MTKView
func makeNSView(context: Context) -> some NSView {
metalView
}
func updateNSView(_ uiView: NSViewType, context: Context) {
}
}
Write this line of code in any file
class Context {}
Hey everyone,
I'm working on implementing an AppLimit, where after accumulating x minutes of Screen Time for an app, it should be blocked. It works fine on the first day, but stops functioning correctly on subsequent days.
What I'm Doing
I start a 24/7 schedule with a DeviceActivityEvent that has a specified Screen Time threshold.
In my DeviceActivityMonitor, I'm reacting to the eventDidReachThreshold. Once the accumulated time is reached, the app is blocked. This works as expected on the first day.
Issues I'm Experiencing / Questions
Second Day Issue: On the second day, the app is no longer blocked after the Screen Time threshold is reached, even though it worked on the first day. This leads me to suspect that a DeviceActivityEvent is "consumable". Is this correct?
Pre-existing Screen Time Issue: If a user has already surpassed the Screen Time threshold before monitoring starts, the app isn't blocked once the schedule is set up. This leads to 2 issues:
I would expect that the accumulated amount of time after starting the schedule would result in the call of eventDidReachThreshold. But it is never called
It could also be the case that the previously accumulated time is being kept in mind, but that would mean the apps should be blocked, which isn't the case.
Does the threshold account for accumulated Screen Time before the schedule begins? I haven't tested setting a limit of 10 minutes, accumulating 3 minutes of Screen Time, then starting the schedule and accumulating the remaining time, but I'm curious if anyone has encountered this behavior.
Does anyone have an explanation for this behavior? Any help would be greatly appreciated!
Hi,
As AppStorage does not support arrays, I found an extension online that allows for handling arrays of strings with AppStorage. However, in my use case, I need to handle arrays of boolean values. Below is the code. Any help would be greatly appreciated.
extension Array: RawRepresentable where Element: Codable {
public init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8),
let result = try? JSONDecoder().decode([Element].self, from: data)
else {
return nil
}
self = result
}
public var rawValue: String {
guard let data = try? JSONEncoder().encode(self),
let result = String(data: data, encoding: .utf8)
else {
return "[]"
}
return result
}
}
Dear,
We are working on a solution that uses MDM to manage devices and create features for our users. As part of this, we want to implement a feature that retrieves the device's location even when the app is closed (killed). Is there a way to achieve this?
Since we are an MDM solution, is there a function available within MDM that allows us to obtain this information?
We are considering implementing the Location Push Service Extension. If we do, will we be able to receive latitude and longitude even if the app is closed?
I have a Swift Coco program taht print a NSView. It work perfectly fine in Monterey but does show the print panel in Sonoma. I cannot find the problem. Here are the 4 errors:
Failed to connect (genericPrinterImage) outlet from (PMPrinterSelectionController) to (NSImageView): missing setter or instance variable
Failed to connect (otherPrintersLabel) outlet from (PMPrinterSelectionController) to (NSTextField): missing setter or instance variable
Failed to connect (localPrintersLabel) outlet from (PMPrinterSelectionController) to (NSTextField): missing setter or instance variable
Failed to connect (genericPrinterImage) outlet from (PMPrinterSelectionController) to (NSImageView): missing setter or instance variable
func createPrintOperation() {
let printOpts: [NSPrintInfo.AttributeKey: Any] = [
.headerAndFooter: false,
.orientation: NSPrintInfo.PaperOrientation.portrait
]
let printInfo = NSPrintInfo(dictionary: printOpts)
printInfo.leftMargin = 0
printInfo.rightMargin = 0
printInfo.topMargin = 0
printInfo.bottomMargin = 0
printInfo.horizontalPagination = .fit
printInfo.verticalPagination = .automatic
printInfo.isHorizontallyCentered = true
printInfo.isVerticallyCentered = true
printInfo.scalingFactor = 1.0
printInfo.paperSize = NSMakeSize(612, 792) // Letter size
// Create a print operation with the view you want to print , myPrintView is a NSView
let printOperation = NSPrintOperation(view: myPrintView, printInfo: printInfo)
// Configure the print panel
printOperation.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize)
printOperation.printPanel.options.insert(NSPrintPanel.Options.showsOrientation)
// Set the job title for the print operation
let jobTitle = fact.nom_complet_f.replacingOccurrences(of: " ", with: "")
printOperation.jobTitle = jobTitle
// Run the print operation
printOperation.run()
}
Hi,
For HTTP requests, I have the following function:
func createAccount(account: Account, completion: @escaping (Response) -> Void) {
guard let url = URL(string: "http://localhost:4300/account") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
guard let encoded = try? JSONEncoder().encode(account) else {
print("Failed to encode request")
return
}
request.httpBody = encoded
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else { return }
do {
let resData = try JSONDecoder().decode(Response, from: data)
DispatchQueue.main.async {
completion(resData)
}
} catch let jsonError as NSError {
print("JSON decode failed: \(jsonError)")
}
}.resume()
}
Because various HTTP requests use different body structs and response structs, I have a HTTP request function for each individual HTTP request. How can I condense this into one function, where the passed struct and return struct are varying, so I can perhaps pass the struct types in addition to the data to the function? Any guidance would be greatly appreciated.
I can’t merge phone calls, people on the phone cannot hear meand I can’t hear them
Alarm doesn’t work sound sometimes. I need to reboot the phone to make sure it works
I need to reboot the phone to make sure it works
3. Cannot update customize wallpaper for home screen. You can update lock screen but not home screen. You can update lock screen but not home screen.
I noticed that running my app in Xcode 16 crashes often. It seems this is due to the strictness Swift 6 adds at runtime. Even after making sure the Swift Language Mode is 5 for the main target and all modules.
I'm migrating to Swift 6 but I probably won't be done before iOS 18 drops so my question is. Can I still ship the app supporting iOS 18 using Xcode 15.4 and Swift 5.10?
I have created my own SPM through File -> New -> Package
Package.swift looks like:
// swift-tools-version: 5.10
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "MyPackage",
platforms: [.iOS(.v16), .macCatalyst(.v16), .macOS(.v14)],
products: [.library(name: "MyPackage", targets: ["MyPackage"]),],
dependencies: [
.package(path: "../external-package")
], targets: [
.target(name: "MyPackage", path: "Sources"),
.testTarget(name: "MyPackageTests", dependencies: ["MyPackage"]),
]
)
When I run swift build the error says:
'.../MyPackage/.build/arm64-apple-macosx/debug/external-package.build/external-package-Swift.h' not found
and surely, when I go to directory:
.../MyPackage/.build/arm64-apple-macosx/debug/external-package.build/
there are only 2 files in there:
module.modulemap & output-file-map.json
All source files from external-package are missing, therefore swift build fails. The only solution I've found is to copy external-package.build folder manually into:
'.../MyPackage/.build/arm64-apple-macosx/debug/`
What am I missing here? Should swift build create those files in there, or they should be resolved somehow differently?
Note: external-package is not in any way unique, this happens to any added dependency
I'm running on macOS 14.6.1 on Apple Silicon M1 Pro with Xcode 15.4
There are some reliable and affordable Polar H10 ECG reader apps available on the App Store: I’ve been using one for a couple of years. However, I recently needed to incorporate an ECG capability into an app that already uses the Polar H10 for RR Interval monitoring,
but the documentation online for Polar ECG is scarce and sometimes incorrect. Polar provides an SDK, but this covers many different devices and so is quite complex. Also, it’s based on RxSwift - which I prefer not to use given that my existing app uses native Swift async and concurrency approaches. I therefore offer this description of my solution in the hope that it helps someone, somewhere, sometime.
The Polar H10 transmits ECG data via Bluetooth LE as a stream of frames. Each frame is length 229 bytes, with a 10 byte leader and then 73 ECG data points of 3 bytes each (microvolts as little-endian integer, two’s complement negatives). The leader’s byte 0 is 0x00, bytes 1 - 8 are a timestamp (unknown epoch) and byte 9 is 0x00. The H10’s sampling rate is 130Hz (my 2 devices are a tiny fraction higher), which means that each frame is transmitted approximately every half second (73/130). However, given the latencies of bluetooth transmission and the app’s processing, any application of a timestamp to each data point should be based on a fixed time interval between each data point, i.e. milliseconds interval = 1000 / actual sampling rate. From my testing, the time interval between successive frame timestamps is constant and so the actual sampling interval is that interval divided by 73 (the number of samples per frame).
I’ve noticed, with both the 3rd party app and my own coding, that for about a second (sometimes more) the reported voltages are very high or low before settling to “normal” oscillation around the isoelectric line. This is especially true when the sensor electrode strap has only just been placed on the chest. To help overcome this, I use the Heart Rate service UUID “180D” and set notify on characteristic "2A37" to get the heart rate and RR interval data, of which the first byte contains flags including a sensor contact flag (2 bits - both set when sensor contact is OK, upon which I setNotifyValue on the ECG data characteristic to start frame delivery).
Having discovered your Polar H10, connected to it and discovered its services you need to discover the PMD Control Characteristic within the PMD Service then use it to request Streaming and to request the ECG stream (there are other streams). Once the requests have been accepted (didWriteValueFor Characteristic) then you start the Stream. Thereafter, frames are delivered by the delegate callback func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) for the characteristic.uuid == pmdDataUUID
The following code snippets, the key aspects of the solution, assume a working knowledge of CoreBluetooth. Also, decoding of data (code not provided) requires a knowledge of byte and bit-wise operations in Swift (or Objective-C).
// CBUUIDs and command data
let pmdServiceUUID = CBUUID.init( string:"FB005C80-02E7-F387-1CAD-8ACD2D8DF0C8" )
let pmdControlUUID = CBUUID.init( string:"FB005C81-02E7-F387-1CAD-8ACD2D8DF0C8" )
let pmdDataUUID = CBUUID.init( string:"FB005C82-02E7-F387-1CAD-8ACD2D8DF0C8" )
let reqStream = Data([0x01,0x02])
let reqECG = Data([0x01,0x00])
let startStream = Data([0x02, 0x00, 0x00, 0x01, 0x82, 0x00, 0x01, 0x01, 0x0E, 0x00])
// Request streaming of ECG data
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?)
if service.uuid == pmdServiceUUID {
for pmdChar in service.characteristics! {
if pmdChar.uuid == pmdControlUUID {
peripheral.setNotifyValue(true, for: pmdChar)
peripheral.writeValue(reqStream, for: pmdChar, type: .withResponse)
peripheral.writeValue(reqECG, for: pmdChar, type: .withResponse)
}
}
}
}
// Request delivery of ECG frames - actual delivery subject to setNotify value
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
// this responds to the reqStream and reqECG write values
if error != nil {
print("**** write error")
return
}
if ecgStreamStarted { return } // I use a flag to prevent extraneous stream start commands
guard let charVal = characteristic.value else { return }
if charVal[0] == 0xF0 && charVal[1] == 0x01 {
peripheral.writeValue(startStream, for: characteristic, type: .withResponse)
ecgStreamStarted = true
}
}
For “live” charting, I create an array of data points, appending each frame’s set on arrival, then provide those points to a SwiftUI View with a TimeLineView(.periodic(from: .now, by:actual sampling interval)) and using Path .addlines with the Y value scaled appropriately using GeometryReader. So far, I’ve found no way of cancelling such a TimeLineView period, so any suggestions are welcome on that one. An alternative approach is to refresh a SwiftUI Chart View on receipt and decoding of each frame, but this creates a stuttered appearance due to the approximately half-second interval between frames.
Regards, Michaela