Foundation

RSS for tag

Access 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

NSTextField and NSAttributedString
I'm trying to put an attributed string in to an NSTextField the user creates in their document. I cannot use an NSTextView. The problem is once the textfield is created attributes cannot be edited. Also I work in Objective-c because reasons. So when the field is created this is the code used: [attribDict setObject:[self.editor.delegate foregroundColor] forKey:NSForegroundColorAttributeName]; [attribDict setObject:aFont forKey:NSFontAttributeName]; [attribDict setObject:[self.editor.delegate backgroundColor] forKey:NSBackgroundColorAttributeName]; [attribDict setObject:self.editor.delegate.strokeColor forKey:NSStrokeColorAttributeName]; [attribDict setObject:[NSNumber numberWithInt:-self.editor.delegate.strokeWidth] forKey:NSStrokeWidthAttributeName]; This part works if I set all the attributes before I create the textfield. But I need to be able to edit attributes on the string. For that I use this code: NSFont * aFont = [NSFont fontWithName:self.delegate.fontSelectorButton.title size:self.delegate.fontSize.intValue]; NSMutableDictionary * attribDict = [[NSMutableDictionary alloc]init]; [attribDict setObject:[self.delegate foregroundColor] forKey:NSForegroundColorAttributeName]; [attribDict setObject:aFont forKey:NSFontAttributeName]; [attribDict setObject:[self.delegate backgroundColor] forKey:NSBackgroundColorAttributeName]; [attribDict setObject:self.delegate.strokeColor forKey:NSStrokeColorAttributeName]; [attribDict setObject:[NSNumber numberWithInt:self.delegate.strokeWidth] forKey:NSStrokeWidthAttributeName]; [textShape updateTextAttributesFromDictionary:attribDict]; And finally this is called the change the string attributes: -(void)updateTextAttributesFromDictionary:(NSDictionary*)attribs { self.stringAttributes = attribs; NSMutableAttributedString * as = [[NSMutableAttributedString alloc]initWithAttributedString:self.myTextField.attributedStringValue]; [as beginEditing]; [as setAttributes:attribs range:NSMakeRange(0, as.length)]; [as endEditing]; self.myTextField.attributedStringValue = as; } I have tried just setting the new attributes and get nothing. The above code however gives me wildly unpredictable results. Sometimes the NSTextfield gets a background color that cannot be altered. Sometimes the text vanishes. Sometimes all attributes are lost, sometimes if I include a stroke color and width I get the stroke but no fill. That's the most common. Is there some fundimental NSTextField short coming I'm missing? Is there something I'm missing with NSAttributedString? Are NSAttributedStrings not compatible with NSTextField?
0
0
333
Feb ’24
Convert unix timestamp to Date failed.
I get and int unix timestamp from database and convert it to timeinterval as some instructions said. But the result date is not correct. the code is as follows: let dateValue = try join.get(examDate); print (dateValue) let timeInterval = TimeInterval(dateValue); print(timeInterval) let date = Date(timeIntervalSince1970: timeInterval) print(date) the result is as follows: 1709942400000 1709942400000.0 56155-12-02 00:00:00 +0000 by converting 1709942400000 with js Date, we got the value: >new Date(1709942400000) 2024-03-09T00:00:00.000Z How can I properly convert unix timestamp to Date object? Thanks in advance.
1
0
627
Feb ’24
NSItemProvider throwing exception related to secure coding
Our app has a share extension. And we recently noticed something with iOS 17.3.1. From Safari, when we receive the plist and try to load it, we are seeing exceptions for classes not allowed to be unarchived. [itemProvider loadItemForTypeIdentifier:[UTTypePropertyList identifier] options:nil completionHandler:^(NSDictionary *jsDict, NSError *error) { } We see these exceptions: value for key 'NS.keys' was of unexpected class 'NSString' (0x1ee7d2970) [/System/Library/Frameworks/Foundation.framework]. Allowed classes are: {( "'NSDictionary' (0x1ee7cad38) [/System/Library/Frameworks/CoreFoundation.framework]" )} (null) Our preprocessing javascript file is basic, and only passes a title and URL as part of the payload. arguments.completionFunction({ "URL": document.URL "title": document.title, });
25
0
1.7k
Mar ’24
URLSession Task Types vs Session Types
I regularly see folks confused as to which URLSession task types are supported in which session types. Here’s a handy reference: Task Type Standard Background --------- -------- ---------- data, convenience yes no data, delegate yes yes [1] download, convenience yes no download, delegate yes yes upload, convenience yes no upload, delegate, data yes no upload, delegate, stream yes no upload, delegate, file yes yes stream yes no WebSocket yes no In this table: A background session is one created from a configuration that was created with the background(withIdentifier:) method. A standard session is one created from some other configuration, namely default or ephemeral. A convenience task is one created by a Swift async method or a method that takes a completion handler. A delegate task is one created otherwise; these signal their completion by calling the urlSession(_:task:didCompleteWithError:) delegate method. For an upload task, the data, stream, and file modifiers indicate how you specify the HTTP request body. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] While it’s possible to run a data task in a background session, this only works if your app avoids suspension while the request is in flight. This is useful in very rare circumstances [2] that most developers never encounter. [2] The specific situation I’m aware of is when you don’t know whether a request’s response will be big (like a file to download) or small (like a status response). To handle this, you start a data task in the background session and, if the response indicates that it’s large, transform it to a download task in your urlSession(_:dataTask:didReceive:completionHandler:) method. (r. 123084713)
0
0
224
Feb ’24
Please help me understand “Finding the Dynamic Type in a Generic Context”
Please help me understand this section! I'm reading Finding the Dynamic Type in a Generic Context that has this snippet: func printGenericInfo<T>(_ value: T) { let t = type(of: value) print("'\(value)' of type '\(t)'") } protocol P {} extension String: P {} let stringAsP: P = "Hello!" printGenericInfo(stringAsP) // 'Hello!' of type 'P' ... that's followed up by this sentence: This unexpected result occurs because the call to type(of: value) inside printGenericInfo(_:) must return a metatype that is an instance of T.Type , but String.self (the expected dynamic type) is not an instance of P.Type (the concrete metatype of value). 1. How come String.self is not an instance of P when I can run this code? func f(_ t: P.Type) { print("...") } f(String.self) 2. Why does type(of:) return the concrete metatype outside but not inside generic functions? print("'\(stringAsP)' of type '\(type(of: stringAsP))'") // 'Hello!' of type 'String'
1
0
252
Feb ’24
Relay http3endpoint gives error : unable to create DATAGRAM flow since the peer did not provide max_datagram_frame_size in transport parameters
I am using Relay to connect to nginx server which supports http3 connections for which I get quic_stream_send_create [C1.1.1.1:5] [24e7c30b6b4eb7ba-0000000000001002e2c0e6cb5099cd86ef1f0f7c] unable to create DATAGRAM flow since the peer did not provide max_datagram_frame_size in transport parameters [C1.1.1.1:3] Unable to send 1200 early bytes quic_stream_send_create [C1.1.1.1:5] [24e7c30b6b4eb7ba-0000000000001002e2c0e6cb5099cd86ef1f0f7c] unable to create DATAGRAM flow since the peer did not provide max_datagram_frame_size in transport parameters This is something very simple I have written : ` let relayURL = URL(string: "https://192.168.64.2:8443")! let relayEndpoint = NWEndpoint.url(relayURL) if #available(iOS 17.0, *) { var tlsOptions = NWProtocolTLS.Options() let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint, tlsOptions: NWProtocolTLS.Options = .init()) let relayConfig = ProxyConfiguration(relayHops: [relayServer]) let config = URLSessionConfiguration.default` config.connectionProxyDictionary = [kCFNetworkProxiesHTTPEnable as AnyHashable: true, kCFNetworkProxiesHTTPProxy as AnyHashable: "192.168.64.2", kCFNetworkProxiesHTTPPort as AnyHashable: 8443, kCFStreamPropertySSLSettings as AnyHashable: sslSettings] config.proxyConfigurations = [relayConfig] // Call addCert to add the certificate to the trust store //addCert(cert: "cert") // Example usage of the custom session let session = makeInsecureURLSession(config: config) let url = URL(string: "https://google.com")! // Example URL let task = session.dataTask(with: url) { data, response, error in // Handle response print("response is \(response)") if let httpResponse = response as? HTTPURLResponse { let protocolUsed = httpResponse.url?.scheme ?? "Unknown" print("Protocol used: \(protocolUsed)") } else { print("Response is not an HTTPURLResponse") } } task.resume()
0
0
327
Feb ’24
URLSession uploadTask not showing progress
I'm having an issue with showing progress in a upload task. I have created a local express app to test it's behavior. But progress / delegate always throughs the same results. I'm also conforming to URLSessionTaskDelegate. This is the way I configure URLSession it's always .default private lazy var session: URLSession = { .init( configuration: self.configuration, delegate: self, delegateQueue: OperationQueue.main ) }() private var observation: NSKeyValueObservation? Then I call it using this func and convert it into a publisher func loadData1(path: String, method: RequestMethod, params: [String: String]) -&gt; AnyPublisher&lt;Data, Error&gt; { let publisher = PassthroughSubject&lt;Data, Error&gt;() guard let imageUrl = Bundle.main.url(forResource: "G0056773", withExtension: "JPG"), let imageData = try? Data(contentsOf: imageUrl) else { return Fail(error: NSError(domain: "com.test.main", code: 1000)).eraseToAnyPublisher() } var request = URLRequest(url: URL(string: "http://localhost:3000/")!) request.httpMethod = "POST" let data = request.createFileUploadBody(parameters: [:], boundary: UUID().uuidString, data: imageData, mimeType: "image/jpeg", fileName: "video") let task = session.uploadTask(with: request, from: data) { data, response, error in if let error = error { return publisher.send(completion: .failure(error)) } guard let response = response as? HTTPURLResponse else { return publisher.send(completion: .failure(ServiceError.other)) } guard 200..&lt;300 ~= response.statusCode else { return publisher.send(completion: .failure(ServiceError.other)) } guard let data = data else { return publisher.send(completion: .failure(ServiceError.custom("No data"))) } return publisher.send(data) } observation = task.progress.observe(\.fractionCompleted) { progress, _ in print("progress: ", progress.totalUnitCount) print("progress: ", progress.completedUnitCount) print("progress: ", progress.fractionCompleted) print("***********************************************") } task.resume() return publisher.eraseToAnyPublisher() } request.createFileUploadBody is just an extension of URLRequest that I have created to create the form data's body. Delegate func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { print(bytesSent) print(totalBytesSent) print(totalBytesExpectedToSend) print("*********************************************") } No matter how big or small is the file that I'm uploading I always get the same results. The delegate is only called once. And the progress is also always the same. progress: 100 progress: 0 progress: 0.0095 *********************************************** progress: 100 progress: 0 progress: 4.18053577746524e-07 *********************************************** 2272436 2272436 2272436 ********************************************* progress: 100 progress: 95 progress: 0.95 *********************************************** progress: 100 progress: 100 progress: 1.0 *********************************************** ^^^^^^ Output from prints Does anyone knows what might I be doing wrong? Thanks in advance
4
0
545
Feb ’24
XCODE 15 - dyld[36278]: Symbol not found: _$s10Foundation13__DataStorageC12replaceBytes2in4with6lengthySnySiG_SVSgSitF
When I run app in iPad in release mode app crashes on launch Only in Xcode 15 it works fine in older Xcodes (14,13 etc) dyld[36278]: Symbol not found: _$s10Foundation13__DataStorageC12replaceBytes2in4with6lengthySnySiG_SVSgSitF Referenced from: <DC51D787-077E-3775-80C8-609FB1460F73> /private/var/containers/Bundle/Application/1A433D08-5BBA-4CEA-A8B1-78ED0777FB2C/MYAPP.app/MyAPP Expected in: <57FF5555-479E-3634-931A-26D334C85350> /System/Library/Frameworks/Foundation.framework/Foundation
2
0
338
Feb ’24
Problems with Observable Macro and Observation: Observable is not member type of class 'Models.Observation'
Hey there i try to adept the Observable macro for my SwiftUI Project. I wanna get data from HealthKit and transform it to FHIR. Here i need one class for managing this process which will be shared through my project in order to access these data. The following Codesnippet raises an error: import Observation import HealthKit import FHIR @Observable class HealthKitManager{ let healthStore = HKHealthStore() init(){ } func requestAuthorization(){ let authTypes: Set = [HKQuantityType(.stepCount), HKQuantityType(.heartRate) ] guard HKHealthStore.isHealthDataAvailable() else { print("health data not available!") return } healthStore.requestAuthorization(toShare: nil, read: authTypes) { success, error in if success { print("OK Fetching") } else { print("\(String(describing: error))") } } } } So the FHIR module contains a Models module which define different models. In the FHIR world there is also a concept called observation... now the problems begin. open class Observation : Models.DomainResource { ... } When i try import Observation for the Observable macro and also import FHIR in order to create Observations, XCode rises an error: Observable' is not a member type of class 'Models.Observation' It's also said that Observation is declared in the FHIR.Models.Observation class which is true, but it seems that this raises the Problem with the @Observable macro. It's also said that Type 'Observation' has no member 'ObservationRegistrar' Which comes from the Observable Macro i think. When i don't import FHIR then everything works fine, but then my use case is broken because i need these standard in order to get my use case running. All in all i need big help and be thankfull for possible solutions!
1
0
472
Feb ’24
Get the creation date of an IntentFile
Is it possible to get the original date created for an IntentFile? The following code always gets the date for right now, surely because it's copied into a temporary directory so that's when it was created at that location. if let fileURL = file.fileURL, fileURL.startAccessingSecurityScopedResource() { if let attributes = try? FileManager.default.attributesOfItem(atPath: fileURL.path), let date = attributes[.creationDate] as? Date { print(date) } fileURL.stopAccessingSecurityScopedResource() }
0
0
355
Feb ’24
Searching data using findRange(of:
The performance of DataProtocol.firstRange(of:) and Collection.firstRange(of:) is different. func testSearch(dataSize: Int = 10_000_000, segmentSize: Int = 1000) { let query = Data([1,1,1]) let data = Data(repeating: 0, count: dataSize) let segments = stride(from: 0, to: dataSize, by: segmentSize) // Search for `query` in `data` using `Data.firstRange(of:` var date = Date.now let result1 = segments.compactMap({ i in data[i..<i+segmentSize].firstRange(of: query) }) print(-date.timeIntervalSinceNow) // 1 sec. // Search for `query` in `data` using `Collection.firstRange(of:` date = .now let result2 = segments.compactMap({ i in data[i..<i+segmentSize].search(for: query) }) print(-date.timeIntervalSinceNow) // 4 secs. assert(result1 == result2) } extension Collection { func search<T: Collection>(for query: T) -> Range<Index>? where T.Element == Element, Element: Equatable { firstRange(of: query) } } To fix, I’m explicitly casting it to Data. extension Collection { func search<T: Collection>(for query: T) -> Range<Index>? where T.Element == Element, Element: Equatable { if let data = self as? Data, let query = query as? Data { return data.firstRange(of: query) as? Range<Index> } else { return firstRange(of: query) } } } This fixes, but doesn’t scale well. Given the method signature is same, how can I write the search function such that it picks up the one in DataProtocol? In my testing, the search results of both are same. Besides the performance, is there any other difference?
0
0
380
Feb ’24
Task <***>.<3> request https://URL is NOT allowed to set HSTS for main doc (null)
One of our client has contacted us with the following error : Task .&amp;lt;3&amp;gt; request https:URL is NOT allowed to set HSTS for main doc (null) Th request is sent from our SDK. According to the client it happens only on Vision Pro. All our requests to the server on the SDK side are https. The serve has the following header: X-Content-Type-Options X-Frame-Options Strict-Transport-Security Can somebody share some insight?
9
0
1.1k
Feb ’24
Get Application Scripts directory for app group
For the current app, I can get the Application Scripts directory with FileManager.url(for: .applicationScriptsDirectory, in: .userDomainMask, appropriateFor: nil, create: true), but I cannot find a similar API for application groups. Does one exist, or do I have to construct the URL manually? That would probably be ~/Library/Application Scripts/[app group id], but there doesn't seem to be a FileManager API to access ~ either, as FileManager.default.homeDirectoryForCurrentUser returns /Users/username/Library/Containers/[app id]/Data/.
4
0
429
Feb ’24
NSKeyedUnarchiver decodeObjectOfClasses failed
I tried to read an Object : -(NSMutableDictionary*) readMyObject:(NSData*)data; { NSError * error; Class class = [NSMutableDictionary class]; NSMutableDictionary * dict; dict = [NSKeyedUnarchiver unarchivedObjectOfClass:class fromData:data error:&amp;error]; return dict; the result was nil. I searched by Developer for a solution and found one : { // NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] init]; [unarchiver decodeObjectOfClasses: [[NSSet alloc]initWithArray: @[[NSDictionary class], [NSMutableDictionary class], [NSArray class], [NSMutableArray class], [NSString class], [NSNumber class]]] forKey:NSKeyedArchiveRootObjectKey]; [unarchiver finishDecoding]; } The first line was from me and it crashed the project. I assume there is an easy answer, not for me.🥲 Uwe
6
0
853
May ’24
HTTP authentication challenges with Swift concurrency
I recently handled a couple of questions about this for DTS, so I thought I’d write it up for the benefit of all. If you have any questions or comments, please put them in a new thread here on DevForums. Tag it with Foundation and CFNetwork so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" HTTP authentication challenges with Swift concurrency URLSession has always made it easy to access HTTP resources, but things get even better when you combine that with Swift concurrency. For example: import Foundation func main() async throws { // Set up the request. let url = URL(string: "https://example.com")! let request = URLRequest(url: url) // Run it; this will throw if there’s a transport error. let (body, response) = try await URLSession.shared.data(for: request) // Check for a server-side error. guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { … handle the error … } // Success. … HTTP response headers are in `response.allHeaderFields` … … HTTP response body is in `body` … } try await main() But what happens if you need to handle an HTTP authentication challenge? The current documentation for authentication challenges is very good, but it assumes that you have a session delegate. That doesn’t really mesh well with Swift concurrency. Fortunately there’s an easier way: Pass in a per-task delegate. Consider this slightly updated snippet: let url = URL(string: "https://postman-echo.com/basic-auth")! let request = URLRequest(url: url) let (body, response) = try await URLSession.shared.data(for: request) This fetches a resource, https://postman-echo.com/basic-auth, that requires HTTP Basic authentication. This request fails with a 401 status code because nothing handles that authentication. To fix that, replace the last line with this: let delegate = BasicAuthDelegate(user: "postman", password: "password") let (body, response) = try await URLSession.shared.data(for: request, delegate: delegate) This creates an instance of the BasicAuthDelegate, passing in the user name and password required to handle the challenge. That type implements the URLSessionTaskDelegate protocol like so: final class BasicAuthDelegate: NSObject, URLSessionTaskDelegate { init(user: String, password: String) { self.user = user self.password = password } let user: String let password: String func urlSession( _ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge ) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { // We only care about Basic authentication challenges. guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic else { return (.performDefaultHandling, nil) } // Limit the authentication attempts. guard challenge.previousFailureCount < 2 else { return (.cancelAuthenticationChallenge, nil) } // If all is well, return a credential. let credential = URLCredential(user: user, password: password, persistence: .forSession) return (.useCredential, credential) } } This delegate handles the NSURLAuthenticationMethodHTTPBasic authentication challenge, allowing the overall request to succeed. Now you have the best of both worlds: An easy to use HTTP API With the flexibility to handle authentication challenges This approach isn’t right for all programs, but if you’re just coming up to speed on URLSession it’s a great place to start.
0
0
297
Jan ’24
Incorrect results from `isSuperset` when used with specific emoji symbols and prefix.
Hi, It seams that the public func isSuperset(of other: CharacterSet) -> Bool API gives inconsistent results for some emoji symbols when uses with and without prefix text. Here is a playground example: import Foundation let input1 = "🥀" let input11 = "a🥀" let input2 = "😀" let input22 = "a😀" let letters = CharacterSet.letters print("'\(input1)' is part of 'CharacterSet.letters': \(letters.isSuperset(of: CharacterSet(charactersIn: input1)))") // Gives false print("'\(input11)' is part of 'CharacterSet.letters': \(letters.isSuperset(of: CharacterSet(charactersIn: input11)))") // INCORRECT: Should give false, but it gives true print("'\(input2)' is part of 'CharacterSet.letters': \(letters.isSuperset(of: CharacterSet(charactersIn: input2)))") // Gives false print("'\(input22)' is part of 'CharacterSet.letters': \(letters.isSuperset(of: CharacterSet(charactersIn: input22)))") // Gives false Output: '🥀' is part of 'CharacterSet.letters': false 'a🥀' is part of 'CharacterSet.letters': true '😀' is part of 'CharacterSet.letters': false 'a😀' is part of 'CharacterSet.letters': false Has anyone observed this?
5
0
442
Jan ’24
Behavior of URLSession with http3RelayEndpoint Proxy config
Hi, I am implementing the HTTP3 Relay server, and testing by the URLSession, let relayEndpoint = NWEndpoint.url(URL(string:"https://localhost:8002")!) let relayServer = ProxyConfiguration.RelayHop( http3RelayEndpoint: relayEndpoint, additionalHTTPHeaderFields: ["Proxy-Authorization":"Basic ***"] ) let relayConfig = ProxyConfiguration(relayHops: [relayServer]) let config = URLSessionConfiguration.default config.proxyConfigurations = [relayConfig] let s = URLSession(configuration: config) I have implemented both the CONNECT method and CONNECT method with :protocol of CONNECT-UDP over HTTP/3. If I enabled CONNECT-UDP only, when I try to connect some HTTP/3 URL like https://quic.aiortc.org/4, it works without problem. And URLSession will use the CONNECT-UDP to connect the UDP channel, throw which the URLSession will do the HTTP/3 request. However, if i enabled both the CONNECT-UDP and CONNECT (for TCP tunnel), the URLSession seems wired. It first try to establish the tunnel for UDP using the CONNECT-UDP method, and then closed it. And finally, it created the TCP tunnel using the CONNECT method. So is there any detailed document for the behavior of the behavior of URLSession with http3RelayEndpoint? Thanks you.
0
0
400
Jan ’24