Post

Replies

Boosts

Views

Activity

Reading Swift/Foundation `AttributedString` attributes
How do I determine the attributes of an AttributedString.Runs.Run? What I'm trying to do I'm trying to reformat Microsoft docx (Word) files (appearance) as TEI XML (semantics). Currently: My lexer ingests the Word file into NSAttributedString and emits events at every change in visible styles (.enumerateAttributes(in:options:using:).). The parser applies hideously ad hoc rules to yield the semantics they reflect. One hopes. (Fun fact: Times New Roman is not in the same family as Times New Roman-Italic.) The start/stop events are derived from the enumerated style runs. Stacking style runs and enqueueing "stop" events do the rest. This is error-prone and graceless, as you must issue start/stop events for many attributes, each readable through one of three or four mutually-exclusive accessors. It works (net of a few weeks at every update), but I'd rather not depend on it. Masochists may see Details, below. Question If I switch to Swift Foundation's AttributedString, how can I iterate runs of common attributes and determine what those attributes are? The mere iteration is easy, but everything I've tried in Playground produces null results or crashes. It would be absurd if Run elements were write-only, there must be a tutorial on how to do it. Where can I look? AttributedString: A new hope The Swift Foundation framework introduces AttributedString, which kinda appears might make this easier. It has a property, .runs, a collection of AttributedString.Runs.Run that identifies ranges and attributes. It has an extensive and extendable repertoire of attributes to apply to the string-in-progress. Every attribute is a first-class value. Writing run properties goes through a consistent, generic interface. Actually, for reading, three or four (functionally identical) interfaces. For building an AttributedString, this is a dream. Reading a Run is a different matter. The API exposes the run Collections, but once you get into them, the documentation (as far as I can tell) halts amid a broken field of Type indices into subscripts; twisty mazes of little attribute names, all alike; used either as subscripts or dynamicCallable modifiers' Type, and calls-as-functions, and nearly all generic; which crash if you try to determine whether they are present in the first place.. (The Book says selecting dynamicCallable, subscript, or call-as-function could be up for judgment. AttributedString solves this problem by exposing all of them. This complaint may be unfair, I wish I could tell.) Everything I've tried in a Playground is wrong. Sometimes the result is null; others, crashes appear as soon as I try to introspect anything. (An "intention" enum is used, as rawValues; unpublished, and too few. Details (if by miracle this is clearer) The first stage in my lexer imports the docx into an NSAttributedString; the second stage of the lexer could yield a stream of attribute-changes and content-text. The parser applies rules (ad-hoc, empirical, and often horrific) to extract the semantics and render them into XML. In other words, LS: Democracy is therefore constrained. yields the stream line-break (short-run-of-bold) ": " (if not part of the bold run) (signal start-of-attribute) (runs of characters, possibly enclosing additional runs) (signal end-of-attribute) line-break [look-ahead] and emit (sorry the forum Markdown doesn't pass XML elements) SPEECH SPEAKER $1 /SPEAKER SPOKEN $2 /SPOKEN /SPEECH` → SPEECH SPEAKER LS /SPEAKER SPOKEN Democracy is therefore constrained. /SPOKEN /SPEECH` AttributedString.run yields a collection, Runs, "an iterable view into segments of the attributed string, each of which indicates where a run of identical attributes begins or ends." A relief to me, if true.
0
0
497
May ’23
Swift compiler errors demand DateFormatter() be unwrapped. Or not.
When I instantiate a DateFormatter, the compiler says the result is optional, and I must unwrap it. When I do, the compiler says the result is not optional, and I must remove all those !'s and ?'s. Should be right let _yyyy_mm_dd: DateFormatter = {     let retval = DateFormatter()     retval.dateFormat = "yyyy-MM-dd"     return retval }() extension Date {     public var ymd: String {         _yyyy_mm_dd.string(from: self)     } } This has happened with a couple of other types, but DateFormatter is easiest to demonstrate. (Apple has from time to time warned that leading underscores are sacred to its frameworks, but in this case, renaming the formatter yyyy_mm_dd had no effect.) Without the bangs (!), as shown above, swiftc flags a syntax error:: error-support.swift:83:5 Value of optional type 'DateFormatter?' must be unwrapped to refer to member 'dateFormat' of wrapped base type 'DateFormatter' - Chain the optional using '?' to access member 'dateFormat' only for non-'nil' base values - Force-unwrap using '!' to abort execution if the optional value contains 'nil' The compiler offers FIXMEs which do exactly as the message suggests. Let's try putting a bang after the initializer: let retval = DateFormatter()! Now I get error-support.swift:82:33 Cannot force unwrap value of non-optional type 'DateFormatter'` I invoke DateFormatter twice, with the same results. Attempting to unwrap the non-optional DateFormatter is a straightforward syntax error. But not unwrapping is flagged as an error, too (though it's non-fatal). This is in a project of about 6500 lines of Swift (counted by cloc, no comments). It works as expected in a playground. Paradox Sometimes these errors go away spontaneously. Sometimes they fail the build. Mostly, the build succeeds anyway; the false alarms disappear, then "Build Succeeded," then the error flags reappaer, but do not interfere with execution. I've done Product → Clear All Issues. I've cleaned the Build Folder repeatedly. A few times I deleted the build directory. All remove the flags. but the next build command shows both success and the error flags. Meditiation DateFormatter is an immediate subclass of NSObject, and has no (visible) override for init(). In principle, one could argue that if [self init] could fail, then so should a direct descendant. There is a universe in which init() would be failable, but not this one. It's supposed to be special-cased. Plea Can you suggest a way to put a stop to these false-alarm errors? We're used to noisy log entries, occasionally nuisance warnings. There shouldn't be nuisance errors. Environment Xcode 14.2 (14C18) macOS 13.2 Ventura MacBook Pro 16" (2021), M1.Pro Memory pressure < 35%, 550 GB free, CPUs maybe above 250% for an instant or two.
3
0
1.3k
Feb ’23
URLSession upload task loops
I'm first going to ask this without full listings and logs, because it feels like the sort of thing that people might recognize generically from their own work. iOS 16 simulator, Xcode 14.2. Aim I want to upload a file to a REST server. I'm using URLSessionUploadTask. HTTP Basic authentication goes through (by the low-level fact that once I provide basic creds, URLSession stops asking). I can assume that the bytes are getting there: My task delegate's urlSession(_:task:didSendBodyData:... is called with the right number of bytes, and equal to the expected number of bytes. I assume that's not a count of what was cast into the net, but the product of some client/server acknowledgement. The minor odd thing is that I see in my logs is first the server-trust auth challenge, then the did-send, and only then HTTPBasic. ∞ Loop The major odd thing is: didReceive challenge: NSURLAuthenticationMethodServerTrust didSend: 296 / 296 didReceive challenge: NSURLAuthenticationMethodHTTPBasic didReceive challenge: NSURLAuthenticationMethodServerTrust didSend: 592 / 592 didReceive challenge: NSURLAuthenticationMethodHTTPBasic ... and so on, ad infinitum, accumulating by multiples of the total data. I admit I have not checked the arithmetic on payload size, I suspect that the count is not necessarily common-sensical. If you have some experience to which the counts are critical, I'm glad to hear from you. The delegate methods for end-of-transfer, success or failure, are never called. The closure argument for URLSession.shared.dataTask... is never called. The server's listing page does not show the file present. Supplement: Multipart Content-Type: multipart/form-data; boundary=593FBDC3-7A99-415D-B6B4-3F553CB6C9C2 --Boundary-593FBDC3-7A99-415D-B6B4-3F553CB6C9C2 Content-Disposition: form-data; name="file"; filename="InputSample.zip" Content-Type: application/zip 0123456 --Boundary-593FBDC3-7A99-415D-B6B4-3F553CB6C9C2- I cam't help the forum's line-wrapping. The linebreaks I intend are \r\n, per the general standard. "0123456" is a part of this package as Data containing that string. I wonder if the promise of .zip content without actual .zip-formatted data is a problem. I hadn't thought J. Random Apache would be that "helpful." Oh, and: My upload task calls .resume() once and only once. Instruments shows no hotspot or deep stack into my code, which I'd expect in a coded infinite loop.
1
0
830
Jan ’23
DocC fails when type/framework/package names collide
When the package, framework, and a type have basically the same name, how do I get DocC to render my custom landing and type pages instead of the defaults? Sometimes I get my landing page to render, sometimes the data type's, never both, often neither Some readers want more of the story: Use case: My package is named SlothWatcher. One of the source files is SlothWatcher.swift, which implements enum SlothWatcher, which serves as a namespace for various constants and functions. I think it's totally reasonable (and common?) to: Name the package SlothWatcher. Name the backbone namespace enum SlothWatcher. Name the file defining the backbone namespace SlothWatcher.swift Enter DocC Now I want DocC to generate documentation. DocC adds some requirements, which are all or some combination of: The docc documentation catalog must be named SlothWatcher.docc. The landing page for the documentation catalog, if overriden, must be named SlothWatcher.md. The first line of that file must be # SlothWatcher (name in double-backticks). All documentation referring to the enum docs must use SlothWatcher/SlothWatcher. Certainly in body text, and I've tried it both ways as the header for the enum extension. If there's a naming rule for the enum extension file, I haven't found it. (Other than that you can't easily put a slash into a file name.) I've lost track. Some of these may not be required at all, given that Xcode defaults none of them. How, if at all, can I get this into working order?
3
0
2.1k
Sep ’21
Xcode 13: "Preparing Editor Functionality" hang?
When I compile my project in Xcode 13, I often see this in the status bar: Preparing Editor Functionality | 114/162 files The multi-progress bubble next to it shows 2⃝ concurrent processes, the preparing… and Indexing | Paused When I run, the app executes, but now there are three tasks, preparing, not-indexing, and running. So I get to build and run, but I'm disturbed to see this apparently-hung progress item. Should I worry?
16
0
9.2k
Sep ’21
Swift Playgrounds & SwiftUI: Playground aborts/crashes with VStack/HStack/ZStack
I'm trying to prototype a SwiftUI.View in Swift Playgrounds (iPadOS 14.4.2, no updates pending). All goes well until I get to any kind of stack view. This is one of those things that could not possibly have passed a unit test, so presumably a configuration exists that doesn't trigger this bug. While I wait for action* on my bug report, can anyone suggest a workaround? Consider this code. It's meant to produce a red circle with a blue boundary. In an Xcode playground, it does. In Swift Playgrounds, starting from an Xcode Playground (or not) template, the page crashes in various ways. The separate Views display as expected. swift import SwiftUI import PlaygroundSupport struct OuterCircle: View {     var body: some View {         Circle( )             .foregroundColor(.blue)     } } struct InnerCircle: View {     var body: some View {         Circle( )             .inset(by: 5.0)             .foregroundColor(.red)     } } struct StackCircle: View {     var body: some View {         ZStack(alignment: .center) {             OuterCircle()             InnerCircle()             // There was a problem encountered while running this playground.             // Check your code for mistakes.         }     } } PlaygroundPage.current.setLiveView(     StackCircle()         .frame(width: 200, height: 200, alignment: .center) ) I've tried every permutation of stacking, View-wrapping, and border/stroke/foreground/fill modifiers I can think of. No change, except for the crash message, which may be the message commented in the code, or the like of "Abort() called", or a BSD synchronization timeout. Moving the component Views into an auxiliary source file merely produced the same error message in an alert instead of in-page. Execution pauses (with a blank canvas) for a few seconds before crashing, and intermediate results do appear in the right margin, so I'd guess this is a runtime thing. I should file a bug — regardless of my "mistakes," Playgrounds shouldn't crash. In the mean time, though, I'd like to get some value. Can anyone suggest a workaround? This question was ostensibly asked and answered at https://developer.apple.com/forums/thread/668268, but the discussion was sidetracked to Xcode and never returned to topic.
2
0
3.3k
Apr ’21
vDSP.correlate(_:withKernel:) — meaning of output
My clients are medical researchers researching methods for characterizing patients' gait from raw accelerometry by matching the data stream against a set of "templates." for the various characteristics. Their (labyrinthine) pseudocode appears to slide a snippet ("template;" kernel?) across a data stream looking for goodness-of-fit by correlation coefficient. This is for each of several templates, so performance is at a premium. As I read the name and the 13-word description, vDSP.correlate(_:withKernel:) does this — in some way. However, the set of numbers that emerge from my playground experiments don't make sense: Identical segments are scored 0.0 (should be 1.0, right?). Merely similar matches show values barely distinguishable from the rest, and are often well outside the range -1.0 ... 1.0. Clearly I'm doing it wrong. Web searches don't tell me anything, but I'm naïve on the subject. Am I mistaken in hoping this vDSP function does what I want? "Yes, you're mistaken" is an acceptable answer. Bonus if you can point me to a correct solution. If I'm on the right track, how can I generate inputs so I can interpret the output as fits my needs? Note: Both streams are normalized to µ = 0.0 and σ = 1.0, by vDSP, and validated by all the unit tests I've done so far.
2
0
1.8k
Feb ’21
Bundle resource path is good; resource URL is nil
Narrative first, exhibits later… Bundle calls that had previously gotten a resource URL from my iOS app's bundle now gets only nil. There is no Bundle or URL call that will return anything but nil. The file is conclusively present. Environment Xcode 11.7, targeting iOS 13.3, SwiftUI, Core Data (store deleted, coordinator reinitialized, obtained a moc, no change to the store). Approach I need to reconstruct my data, so I want to read a not-insanely-large JSON file. Before installing Xcode 11.7, this was no problem: Bundle would give me a URL for the file, nothing remarkable. That version of the read appears in the listing below after the /*&#92;&#42;&#92;&#42;...&#92;&#42;&#92;&#42;*/ line. I'd let the project sit for a couple of weeks, during which I installed Xcode 11.7. (I'm allowing for the new version being a red herring.) Now, Bundle$url(forResource:withExtension:) returns nil. I tried a number of workarounds and double-checks: The file is there, Bundle will supply a path string. The path works, so I have a workaround, but this bothers me. What I checked Bundle$path(forResource:ofType:) returns a path that proves valid on the command line and in Finder. Data can be recovered from that path. Opening the .app package in Finder shows a file of that name in the top level of the package. Same with the command line. expr try FileManager.default.contentsOfDirectory(atPath: Bundle.main.bundlePath) on the LLDB command line shows the file name in the list. The file is there. There was no way to initialize a URL from the path, URL(fileURLWithPath:), trying to get a URL for the bundle path… everything I could think of. Always nil. Deleting all Simulator devices under ~Library did nothing. Neither did removing and restoring the iPhone 8 simulator in the Devices and Simulators window. Nor deleting DerivedData. I routinely do sudo xcrun xcode-select -s /Applications/Xcode.app whenever I install a new Xcode. Remaining confounders When 11.7 opened the project, it downloaded and installed the Swift packages for Alamofire and KDTree. The .app name has a space in it. Astonishing regression if that's it. I haven't tried reproducing this in a fresh project, or the like. Gotta stop some time. Code let countyMetadata: [CountyWithCentroid] = {     var stage = "Path"     do {         let vanillaDecoder = JSONDecoder() /****************** DOES WORK ******************/         let pCentroidPath = Bundle.main             .path(forResource: &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;"WithGeometryAndPopulation", &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; ofType: "json")&#9; &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; // =>&#9; /* /Users/fritza/Library/Developer/CoreSimulator/Devices/65C9CC3A-9A49-4131-BF4C-535702B73559/data/Containers/Bundle/Application/908E5688-04A5-417B-BF4B-3C482735E25B/County Trends.app/WithGeometryAndPopulation.json/         let pData = FileManager.default &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.contents(atPath: pCentroidPath!) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; // =>&#9;1_585_677 bytes         let pCentroidRecords = try vanillaDecoder             .decode([CountyWithCentroid].self, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; from: pData!) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; // =>&#9;3140 elements /******************* HAD WORKED ******************/         stage = "URL"         let cCentroidURL = Bundle.main &#9;&#9;&#9;&#9;&#9;&#9; .url(forResource: &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; "WithGeometryAndPopulation", &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;withExtension: "json")&#9; &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; // =>&#9; nil         let cCentroidData = try Data(contentsOf: cCentroidURL!) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; // =>&#9; Dereference of nil.         let cCentroidRecords = try vanillaDecoder             .decode([CountyWithCentroid].self, from: cCentroidData)         return cCentroidRecords     }     catch { &#9;&#9;// ...     }     return [] }()
2
0
3.5k
Sep ’20
UIColor(patternImage:) doesn't render in SwiftUI
This is SwiftUI written in Xcode 11.6, targeting iOS 13. Has anyone gotten a UIColor initialized from a pattern image to render in the presence of SwiftUI? I have a function that creates a UIImage 128x128 pattern of diagonal lines. The intention is to pass it to UIColor.init(patternImage:) So, two products, the image and the pattern color. Works When I render the images, they look fine, in Playground, in the Xcode debugger, in SwiftUI.Image, in a UIImageView of a pure-UIKit app. The colors render as the backgroundColor for a UIView in a pure-UIKit app. In all cases, the pattern color shows in the console as a UIColor wrapping an image. Doesn't work The pattern colors render nowhere else, simulator or device. Playground "previews" the color (SwiftUI not imported) as "Unable to encode pattern colors at this time." No logs in any other environment. Intended use The intended use is as the fill color for an MKOverlay: Areas are rendered in colors according to a statistic; where the statistic is unavailable, I'd like to hash the overlay out. The map delegate's method mapView(_:rendererFor:) creates the renderer, sets the fill color to the pattern, sets alpha to 1.0. The overlays render as approximately black, 50% alpha. Moving the delegate object to a file importing only UIKit and MapKit doesn't make the pattern color render. What am I missing? I've heard pattern colors aren't supported by SwiftUI, but I wouldn't think it'd poison code in a UIKit enclave. They're supposed to be interoperable, right? "Don't worry, you can adopt in phases?"
0
0
1.1k
Aug ’20
Caching MapKit coordinates
I am rendering lots of MapKit overlays. MapKit overlays are specified in terms of MKMapPoint's. I'd like to save the effort of translating GeoJSON text coordinates into MK polygons every time the app executes. The docs say I should stick to CL ~spherical coordinates and not store MK points. As a practical matter, can I store MK geometry if it's just a local cache and never shared? I am working with a dataset of polygons (US counties) with about 4000 elements. My source format is GeoJSON, for which MapKit has a reader. The process, as I imagine it, starts with a String-to-Double interpreter that yields CLLocationCoordinate2D's (or equivalent intermediates). For MapKit to render a run of CL coordinates as a polygon, they must be translated (internally or through a convenience init) into aggregates of MKMapPoint's, resolving the spherical coordinates into projected graphical coordinates. Let's stipulate that this pipeline is as efficient as the best minds can make it. Suppose I want to save as much decoding time as possible by storing arrays of binary coordinates as Data blobs in CoreData. Encoding an array of CL coordinates is a wIn as far as it goes. Extending the CL struct for NSCoding isn't hard. Naïvely, encoding an array of MK coordinates would be an even bigger win. The documentation, however, says I shouldn't persist MK coordinates. I can imagine why. The coordinate mapping MapKit uses might differ across architectures and OS versions. These wouldn't be stable across contexts, even for a single user: Not only could she not share the translated points, but she couldn't upgrade the OS or buy a new phone. (I want her to upgrade her operating system. Apple wants her to buy a new phone.) Certainly I couldn't bake a translated gazetteer into the app; I'd have to cache an interpretation of the GeoJSON as part of onboarding. If update rot turns out not to be a thing. Right? Is there a loophole? One that would allow me to generate and cache MK geometry at every run? Is there a cache directory I can expect the OS to purge upon OS updates and hardware changes? And would that be enough? (Checking MK's arithmetic before using the cached values smells.) Or should I back off and be happy with caching the JSON → CL locations?
0
0
978
Jul ’20