Hello,
I'm working on adding a URLSessionWebSocketTask based web socket connection to have live data in a single view. When the user navigates to it, the connection is established and live data is received. The task is being cancelled when this view disappears:
task.cancel(with: .goingAway, reason: nil)
After calling resume() on the task, I ping the server to see if the connection works before sending any messages. I opt to use async API instead of closure based wherever possible. Foundation provides both APIs for most URLSessionWebSocketTask's methods, but for some reason it misses async version of sendPing.
Such method, however, is available in swift-corelibs-foundation project here. So I've added a similar code locally:
extension URLSessionWebSocketTask {
func sendPing() async throws {
let _: Void = try await withCheckedThrowingContinuation { continuation in
sendPing { error in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume()
}
}
}
}
}
The issue that I have is that if the user navigates from the view after sendPing was called, but before pong is received, pongReceiveHandler is called twice with error:
Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={NSDescription=Software caused connection abort}
This results in an exception:
Fatal error: SWIFT TASK CONTINUATION MISUSE: sendPing() tried to resume its continuation more than once, throwing Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={NSDescription=Software caused connection abort}!
There are no issues when the task is cancelled after successful ping.
The documentation does not state that pongReceiveHandler is always called only once, but by looking at the code in swift-corelibs-foundation I think that it should be the case.
Am I misusing sendPing, or is it a bug in the Foundation? Perhaps there is no func sendPing() async throws for some reason?
I use Xcode 15.3 with Swift 5.10.
Great thanks for any help.
Best Regards,
Michal Pastwa
Foundation
RSS for tagAccess essential data types, collections, and operating-system services to define the base layer of functionality for your app using Foundation.
Posts under Foundation tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
In app delegate I'm trying to load an array with strings from a plist. I print the plist it prints fine...
func loadTypesArray() {
guard let path = Bundle.main.path(forResource: "Types", ofType: "plist") else {return}
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
guard let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil) as? [String] else {return}
print(plist)
typesArray = plist
// print(typesArray)
}
But when I try and access it from a different part of the app using let typesArray = AppDelegate().typesArray
the array I get is an empty array! any help?
The following program demonstrates the issue. It prints:
y = 2.000000
CGRectMake symbol not found
What would cause the symbol not to be found when using the dlopen/dlsym functions?
#import <CoreGraphics/CoreGraphics.h>
#import <dlfcn.h>
int main(int argc, const char * argv[])
{
CGRect rect = CGRectMake(1.0, 2.0, 3.0, 4.0);
printf("y = %f\n", rect.origin.y);
void * handle = dlopen("/System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics", RTLD_LAZY);
if (handle == NULL) {
printf("handle == NULL\n");
}
else if (dlsym(handle, "CGRectMake") == NULL) {
printf("CGRectMake symbol not found\n");
}
return 0;
}
I am observing this issue with other symbols as well. What is special about them?
I've created a UserDefaults extension to generate custom bindings.
extension UserDefaults {
func boolBinding(for defaultsKey: String) -> Binding<Bool> {
return Binding (
get: { return self.bool(forKey: defaultsKey) },
set: { newValue in
self.setValue(newValue, forKey: defaultsKey)
})
}
func cardPileBinding(for defaultsKey: String) -> Binding<CardPile> {
return Binding (
get: { let rawValue = self.object(forKey: defaultsKey) as? String ?? ""
return CardPile(rawValue: rawValue) ?? .allRandom
},
set: { newValue in
self.setValue(newValue.rawValue, forKey: defaultsKey)
})
}
}
For the sake of completeness, here is my enum
enum CardPile: String, CaseIterable {
case allRandom
case numbers
case numbersRandom
case daysMonths
case daysMonthsRandom
}
I've also created UI elements that use these bindings:
var body: some View {
VStack {
Toggle("Enable", isOn: UserDefaults.standard.boolBinding(for: "enable"))
Picker("Card Pile", selection: UserDefaults.standard.cardPileBinding(for: "cardPile")) {
ForEach(CardPile.allCases,
id: \.self) {
Text("\($0.rawValue)")
.tag($0.rawValue)
}
}
}
}
When I tap the toggle, it updates correctly. However when I tap the picker and select a different value, the binding setter gets called, but the view does not refreshed to reflect the change in value. (If I force quit the app and re-run it, the I see the change.)
I would like to find out why the Binding works as I'd expected (ie updates the UI when the value changes) but the Binding behaves differently.
any/all guidance very much appreciated.
Note: I get the same behavior when the enum use Int as its rawValue
Hello,
For educational purpose, I try to use a POSIX semaphore sem_t instead of a dispatch_semaphore_t in a sandbox macOS Obj-C app.
When using sandbox, the semaphore code creation :
sem_t * _unixSemaphore;
char nameSemaphore[64] = {0};
snprintf(nameSemaphore, 22, "/UnixSemaphore_sample");
_unixSemaphore = sem_open(nameSemaphore, O_CREAT, 0644, 0);
fails, receiving SEM_FAILED and the errno is 78 (not implemented)
However, the sem_t _unixSemaphore is created and works fine when I disable sandbox I my entitlements.
Is there a way to fix this?
Thank you in advance
Jean Marie
I'm building a macOS target for my App (which also has some Obj-C code).
Building and running the app is fine but when I archive the app in XCode, the process / build fails with the following error
Type 'BOOL' (aka ;Int32') cannot be used as a boolean;test for '!=0' instead
It happens in a couple of places, one of the places being
private func getRootDirectory(createIfNotExists: Bool = true) throws -> URL {
return try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
}
where it complains that create: true is not acceptable and throws the above error.
If I comment out this line, the archive works successfully.
When i Cmd + click the definition of Filemanager.default.url , i get this
@available(macOS 10.6, *)
open func url(for directory: FileManager.SearchPathDirectory, in domain: FileManager.SearchPathDomainMask, appropriateFor url: URL?, create shouldCreate: BOOL) throws -> URL
This looks fishy since it it says create shouldCreate: BOOL whereas the documentation says it should be just Bool
func url(
for directory: FileManager.SearchPathDirectory,
in domain: FileManager.SearchPathDomainMask,
appropriateFor url: URL?,
create shouldCreate: Bool
) throws -> URL
My minimum deployment target is macOS 13.0
I'm quite stumped at this error - which happens only while archiving. Does anybody know why?
[quote='751689021, Vlobe42, /thread/751689, /profile/Vlobe42']
this is an email I have sent to Apple with no luck:
Dear Apple Developer Support Team,
I am writing to seek urgent assistance with a persistent issue I
have been encountering with Xcode. For several months now, every
time I connect my iPhone to Xcode for development purposes, it
automatically overwrites the user data of my apps with an old,
seemingly random container. This issue is severely impacting my
ability to continue development, as I cannot test new changes
effectively. This occurs since a few months in every iOS and
Xcode/macOS Version. I tried it with different Apps and Devices.
Sometimes the entire Container (Documents) gets read only access so
no new data can be created or changed by the user.
I frequently used the replace container feature on Xcode so maybe
this has something to do with it.
This problem persists despite numerous attempts to resolve it on my
end. I am at a critical point in my development timeline, and it is
crucial for me to resolve this as soon as possible.
Could you please advise on the next steps I should take to address
this issue? If there are any logs or further information you
require, I am more than willing to provide them.
Thank you for your attention to this matter. I look forward to your
prompt response and hope for a resolution soon.
Best regards,
Victor Lobe
[/quote]
Hi there,
I am encountering an issue in my project which utilizes a speech recognizer and occasionally plays audio files. The problem arises when I configure the AVAudioSession and enable voice processing. The system volume changes unexpectedly and becomes uncontrollable. Specifically, the volume is excessively loud on iPhone but quite low on iPad
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker, .allowBluetooth, .interruptSpokenAudioAndMixWithOthers])
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
try audioEngine.inputNode.setVoiceProcessingEnabled(true)
try audioEngine.outputNode.setVoiceProcessingEnabled(true)
I have provided a sample project here: Sample Project.
To reproduce the issue, please follow these steps on a real device:
Click on "Play recording" to hear the sound at normal volume.
Click on "Start recording" to set up the category and speech recognizer.
Click on "Stop recording" to stop the recording.
Click on "Play recording" again and observe that the sound volume has changed.
Thank you for your assistance.
How do I switch a thread in my app to use ARM’s big endian mode? The thread code is complied in with the app using Xcode; however other ways of compiling/linking such as libraries, support threads or even cooperative apps might work. Open to ideas. I need to get the iPad processor into big endian mode. Please feel free to ask for any additional information. Best, BR.
We would like to be able to modify the display name of our app in the dock and finder (etc) but not change the name of the .app bundle.
We've tried modifying CFBundleName and CFBundleDisplayName in Info.plist, but this doesn't seem to have an effect.
Is there any way to have the displayed name be different from the base name of the app bundle? We want this to apply for all languages.
Thanks!
Hello fellow iOS developers!
Using a simple app with only print lines in the SceneDelegate class, all other tested devices running iOS 17.5.1 (iPad Pro M4, iPad Pro 3rd Generation, iPhone XR) exhibit this behavior when turning off the screen using the side button:
2024-05-31 21:21:13.0260 --sceneWillResignActive
2024-05-31 21:21:13.0290 --sceneDidEnterBackground
This is the same as when putting the app in the background.
However, the iPhone 15 Pro Max running iOS 17.5.1 does this:
2024-05-31 9:08:28.4580 PM --sceneWillResignActive
2024-05-31 9:08:29.8310 PM --sceneDidBecomeActive
2024-05-31 9:08:29.8490 PM --sceneWillResignActive
2024-05-31 9:08:29.8510 PM --sceneDidEnterBackground
I’ve also submitted this as a potential bug in the Feedback Assistant. Does anyone know why sceneDidBecomeActive() is invoked when turning off the screen with the side button in this specific case?
I’m aware that using Face ID causes the app to briefly experience sceneDidBecomeActive() followed by sceneWillResignActive() during biometric authentication, and then switches back to sceneDidBecomeActive() once authentication completes. But why does this odd behavior occur when turning the screen off in simple app?
Is there a way to detect that the side button has been pressed to turn off the screen?
Thank you in advance,
--SalCat
I am using NSURLSession for file upload and need to satisfy the following scenarios:
Large file uploads
Upload tasks should not be interrupted when the app is running in the background
After the file upload is completed, the server returns a JSON data to inform the app of some information.
When I debug with the my code attached below, I found that the
urlSession(_:task:didCompleteWithError:)
method is correctly called after the upload is completed,
BUT the
urlSession(_:dataTask:didReceive:)
method is never called.
Since I need to read the response data from the server after a successful file upload, if the urlSession(_:dataTask:didReceive:) method is not called, where should I get the server's response data from?
PS: When I change URLSessionConfiguration.background to let config = URLSessionConfiguration.default, I can create the upload task with URLSession.uploadTask(with: request, fromFile: fileURL, completionHandler:) and get the server response data in the completionHandler.
import Foundation
class FileUploader: NSObject, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDataDelegate {
public typealias ProgressHandler = (_ bytesSent: Int64, _ totalBytes: Int64) -> Void
public typealias CompletionHandler = (Error?, Data?) -> Void
private var session: URLSession!
private var responedData: Data?; // to hold data responsed from sever
private var progressHandler: ProgressHandler?
private var completionHandler: CompletionHandler?
override init() {
super.init()
let config = URLSessionConfiguration.background(withIdentifier: "com.example.LABackgroundSession")
session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
}
func upload(fileURL: URL, to url: URL) {
var request = URLRequest(url: url)
request.httpMethod = "POST"
let uploadTask = session.uploadTask(with: request, fromFile: fileURL)
uploadTask.resume()
}
// MARK: - URLSessionDataDelegate methods
public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
self.progressHandler?(totalBytesSent, totalBytesExpectedToSend);
}
//This method never called, and there is no other way i can get the response data.
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
self.responedData?.append(data);
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let error = error {
self.completionHandler?(error, self.responedData)
} else {
self.completionHandler?(nil, self.responedData);
}
self.responedData = nil;
}
}
It seems that that all the crashes are coming from the same place BUT the error is slightly different.
Attaching the code that responsible for the crash:
static NSString * const kDelimiter = @"#$@";
+ (PNDArray *)getObjectsFromData:(NSData *)data {
NSString *dataStr = [[NSString alloc] initWithData:data encoding:encoding];
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"\\u0000" withString:@""];
NSArray *components = [dataStr componentsSeparatedByString:kDelimiter];
NSMutableArray *result = [NSMutableArray array];
for (NSString *jsonStr in components) {
if (jsonStr != nil && jsonStr.length != 0 && ![jsonStr hasPrefix:kBatchUUID]) {
[result addObject:jsonStr];
}
}
return [PNDArray arrayWithArray:result];
}
2024-04-16_17-15-34.1922_-0600-dfa2faecf702f23e3f6558bea986de4f62851761.crash
2024-04-24_04-56-53.4664_-0500-6b125d3d03b7e497b6be339c2abb52f29658824b.crash
2024-04-25_11-13-53.1326_-0700-bfe370be3eae8d65f465eac714905dd3d13aa665.crash
2024-05-03_11-47-36.6085_-0500-2793587e7ed1c02b0e4334bbc3aa0bd7f7a0cf3d.crash
2024-05-05_10-49-40.5969_-0700-4d86636b0877fceb8c0cdb9586ee16dfb0a9c934.crash
There are several crash logs
Crashed: com.apple.root.default-qos
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000038
0 CFNetwork 0x1e98 CFURLRequestSetHTTPRequestBody + 36
1 *** 0x104f7d0 -[XXXRequest getURLRequest] + 66 (XXXRequest.m:66)
2 *** 0x1051328 -[XXXRequestManager processHTTPRequest:] + 152 (XXXRequestManager.m:152)
3 *** 0x79748c __47-[XXXLog __submit:]_block_invoke + 277 (XXXLog.m:277)
4 FBLPromises 0x5138 __56-[FBLPromise chainOnQueue:chainedFulfill:chainedReject:]_block_invoke.18 + 52
5 libdispatch.dylib 0x63094 _dispatch_call_block_and_release + 24
6 libdispatch.dylib 0x64094 _dispatch_client_callout + 16
7 libdispatch.dylib 0x6924 _dispatch_queue_override_invoke + 924
8 libdispatch.dylib 0x13b94 _dispatch_root_queue_drain + 340
9 libdispatch.dylib 0x1439c _dispatch_worker_thread2 + 172
10 libsystem_pthread.dylib 0x1dc4 _pthread_wqthread + 224
11 libsystem_pthread.dylib 0x192c start_wqthread + 8
Hello, I'm Trying to learn swift and looking for resources to learn swift UI and try to create a basic web browser app for ios and mac. (using webkit). Does anyone have any type of tips and tricks to perform this? Thank you ahead of time.
I'm using a file descriptor to write into a file. I've encountered a problem where if the underlying file is removed or recreated, the file descriptor becomes unstable. I have no reliable way to confirm if it's writing on the expected file.
let url = URL(fileURLWithPath: "/path/")
try FileManager.default.removeItem(at: url)
FileManager.default.createFile(atPath: url.path, contents: .empty)
let filePath = FilePath(url.path)
var fileDescriptor = try FileDescriptor.open(filePath, .readWrite)
// The file is recreated - may be done from a different process.
try FileManager.default.removeItem(at: url) // L9
FileManager.default.createFile(atPath: url.path, contents: .empty) // L10
let dataToWrite = Data([1,1,1,1])
try fileDescriptor.writeAll(dataToWrite) // L13
let dataWritten = try Data(contentsOf: url)
print(dataToWrite == dataWritten) // false
I would expect L13 to result in an error. Given it doesn't:
Is there a way to determine where fileDescriptor is writing?
Is there a way to ensure that fileDescriptor is writing the content in the expected filePath?
Before anyone rants and raves about checking documentation - I have spent the last 4 hours trying to solve this issue on my own before asking for help. Coding in Swift is VERY new for me and I'm banging my head against the wall trying to teach myself. I am very humbly asking for help. If you refer me to documentation, that's fine but I need examples or it's going to go right over my head. Teaching myself is hard, please don't make it more difficult.
I have ONE swift file with everything in it.
import Foundation
import Cocoa
import Observation
class GlobalString: ObservableObject {
@Published var apiKey = ""
@Published var link = ""
}
struct ContentView: View {
@EnvironmentObject var globalString: GlobalString
var body: some View {
Form {
Section(header: Text("WallTaker for macOS").font(.title)) {
TextField(
"Link ID:",
text: $globalString.link
)
.disableAutocorrection(true)
TextField(
"API Key:",
text: $globalString.apiKey
)
.disableAutocorrection(true)
Button("Take My Wallpaper!") {
}
}
.padding()
}
.task {
await Wallpaper().fetchLink()
}
}
}
@main
struct WallTaker_for_macOSApp: App {
@AppStorage("showMenuBarExtra") private var showMenuBarExtra = true
@EnvironmentObject var globalString: GlobalString
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(GlobalString())
}
// MenuBarExtra("WallTaker for macOS", systemImage: "WarrenHead.png", isInserted: $showMenuBarExtra) {
// Button("Refresh") {
//// currentNumber = "1"
// }
// Button("Love It!") {
//// currentNumber = "2"
// }
// Button("Hate It!") {
//// currentNumber = "3"
// }
// Button("EXPLOSION!") {
// // currentNumber = "3"
// }
////
// }
}
}
class Wallpaper {
var url: URL? = nil
var lastPostUrl: URL? = nil
let mainMonitor: NSScreen
init() {
mainMonitor = NSScreen.main!
}
struct LinkResponse: Codable {
var post_url: String?
var set_by: String?
var updated_at: String
}
struct Link {
var postUrl: URL?
var setBy: String
var updatedAt: Date
}
func parseIsoDate(timestamp: String) -> Date? {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
return formatter.date(from: timestamp)
}
func fetchLink() async {
do {
url = URL(string: GlobalString().link)
let (data, _) = try await URLSession.shared.data(from: url!)
let decoder = JSONDecoder()
let linkResponse = try decoder.decode(LinkResponse.self, from: data)
let postUrl: URL? = linkResponse.post_url != nil ? URL(string: linkResponse.post_url!) : nil
let date = parseIsoDate(timestamp: linkResponse.updated_at)
let link = Link(
postUrl: postUrl,
setBy: linkResponse.set_by ?? "anon",
updatedAt: date ?? Date()
)
try update(link: link)
} catch {
}
}
func update(link: Link) throws {
guard let newPostUrl = link.postUrl else {
return
}
if (newPostUrl != lastPostUrl) {
lastPostUrl = newPostUrl
let tempFilePath = try getTempFilePath()
try downloadImageTo(sourceURL: newPostUrl, destinationURL: tempFilePath)
try applyWallpaper(url: tempFilePath)
} else {
}
}
private func applyWallpaper(url: URL) throws {
try NSWorkspace.shared.setDesktopImageURL(url, for: mainMonitor, options: [:])
}
private func getTempFilePath() throws -> URL {
let directory = NSTemporaryDirectory()
let fileName = NSUUID().uuidString
let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])!
return fullURL
}
private func downloadImageTo(sourceURL: URL, destinationURL: URL) throws {
let data = try Data(contentsOf: sourceURL)
try data.write(to: destinationURL)
}
}
The 'fetchLink' function is where things explode, specifically when setting the URL. I do not know what I'm doing wrong.
We are using Manged App Configurations to dynamically push values to our app. We eventually want these values to reach our Network Extension process (specifically PacketTunnelProvider).
However, there's some problems here:
MDM providers only allow us to send configurations to app, not the extension. There's not really a way for us to reach the app configuration from the extension (even if the extension and app are in the same app group), because the app config is placed in [NSUserDefaults standardUserDefaults]
A workaround would then be for the app to monitor for any AppConfig changes using NSUserDefaultsDidChangeNotification, and then write the app config settings to a shared NSUserDefaults instance. But when the app is in the background (most of the time for network extension apps), those notifications don't fire. I've attempted to use KVO to notify on any changes such as below:
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"com.apple.configuration.managed" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%@", [change description]);
}
But I am not seeing any KVO notifications here, even when NSUserDefaultsDidChangeNotification fires.
This would be a workaround, but if the app is not running (due to connect-on-demand) or some other reason, this still would not work.
Is there any possible workarounds or things that we can do here? Any help would be appreciated. Thanks
I am working on an app that is streaming data from a bluetooth device to an iPhone. As data constantly arrives to the phone, I am repeatedly decoding data segments and sending it to a file through a OutputStream (from Foundation).
Trying to streamline this background work, I want to make sure the data I/O is using a buffered write. Looking over documentation for the OutputStream class, I cannot find any mention of how to flush the buffer if needed, and am unsure if the Stream object is using a buffer across my repeated calls.
Are OutputStreams sending binary data to a file buffered or unbuffered?
Thank you in advance for clarifying this mechanic!
I am using XCode Version 15.3, and Swift 5.10
I am trying to develop an app that runs on iMacs, iPhones and iPads. so how, using SwiftUI, do I check what device I am running on?