Hello! I am working on a project that does some automatic code generation using SwiftSyntax and SwiftSyntaxBuilder. As part of this project, I want to put in a comment at the top of the file warning users to not modify the file and make it obvious that the code was automatically generated. I was trying to use the .lineComment(String) static member of the Trivia (or TriviaPiece) types and I expected that the comment would automatically be prefixed with the expected // and space for use in code. (For example, Trivia.lineComment("No comment") would be written as // No Comment when sent through a BasicFormat Object or similar SyntaxRewriter). I was surprised to find that this is not the case and was wondering before I write an issue on GitHub whether this behavior is intentional or a bug. If it is intentional, I'm not entirely sure if I'm missing something regarding this to more easily generate these comments.
At the moment my comment generation consists of constructing the comment in the leadingTrivia of the syntax node that appears after the comment. For example:
VariableDeclSyntax(leadingTrivia: [.newlines(2), .lineComment("// These members are always generated irrespective of the contents of the generated files. They are intended to exclusively centralize code symbols that would otherwise be repeated frequently."), .newlines(1)], modifiers: [DeclModifierSyntax(name: .keyword(.private)), DeclModifierSyntax(name: .keyword(.static))], .let, name: PatternSyntax(IdentifierPatternSyntax(identifier: "decoder")), initializer: InitializerClauseSyntax(value: ExprSyntax(stringLiteral: "\(configuration.decoderExpression)")))
outputs
// These members are always generated irrespective of the contents of the generated files. They are intended to exclusively centralize code symbols that would otherwise be repeated frequently.
private static let decoder = JSONDecoder()
in this project (with example data having been added).
Post
Replies
Boosts
Views
Activity
Hello! I'm having difficulties getting Xcode Cloud to see new changes to my files in my project that are being pushed. Previously, this was due to some network situation on my GitLab self-hosted server. This has likely been changed but I'm having difficulties because I tried to use an integration in GitLab for App Store Connect which isn't the same as Xcode Cloud and so as a result it didn't work. I tried starting over and setting up the system from scratch but the web hook hasn't appeared as it had done the first time I set it up.
Does anyone know how to set up the web hook manually for Xcode Cloud so that Xcode Cloud is notified when a new push and other relevant events occur in my repository? The web hook that was previously there would error when I tried testing it on the GitLab end, but since I had deleted it, the web hook is not longer present and I was unable to recreate it as part of the setup procedure because it was pretty opaque to me the first time around and I followed the procedure in the documentation to get it to work. Xcode Cloud works fine when I manually start a build.
I'm trying to make a macro that has the following structure:
@SampleDataProviding(decoder: JSONDecoder(), bundlePath: Bundle.module.bundlePath, fileExtension: "json")
The primary issue that I am having is that I need to be able to scan a subdirectory of the bundlePath for files that match a certain criteria. However, when I try to access the Bundle.module.bundlePath it literally spits back at me "Bundle.module.bundlePath" which obviously doesn't get me anywhere. I've looked all over for a way to convert what I enter at the macro call site to an actual path that I can put in code that isn't generated. (This macro goes through a specific subdirectory looking for sample data files which it then generates a variable expression for each of them so that it is easy to access this sample data (for UI work or testing).) Each time I try this it fails stating that the folder doesn't exist because it's looking for "Bundle.module.bundlePath/[subdirectory]" when I want it to look for the subdirectory in the bundle path, not "Bundle.module.bundlePath". I've been able to get this to work in testing by wrapping the call in an interpolation from a string but this does not work in the real world because the compiler complains that the interpolation cannot be modified (it is also more clunky, I would prefer to avoid having to wrap the entire thing in an interpolation).
I've written a Swift package plugin to add the colours provided in the asset bundles in an extension of the SwiftUI Color type but I'm having difficulties testing this since the bundle and/or colour that is in the asset catalogs are not yet loaded when XCTest goes to evaluate the test conditions. Here is my test code: (colours are just random colours, some derive from macOS colour picker; also, the new static method is functionality that I added and is not present in the existing Color APIs)
final class TestCase: XCTestCase {
func testBanana() {
XCTAssertEqual(Color.banana, Color.new(from: "FEFC78")!)
}
func testAlexsColor() {
XCTAssertEqual(Color.alexsColor, Color.new(from: "0432FF")!)
}
func testMaximumPowerColor() {
XCTAssertEqual(Color.maximumPower, Color.new(from: "FF2600")!)
}
func testLongNameColor() {
XCTAssertEqual(Color.reallyLongNameThatJustKeepsGoingOnAndOnAndOnAndOn, Color.new(from: "AAA000"))
}
}
Here is an example error message that I get when I run the test:
testBanana(): XCTAssertEqual failed: ("NamedColor(name: "Banana", bundle: Optional(NSBundle </Users/trevorhafner/Library/Developer/Xcode/DerivedData/TransportBase-cbagdabrompfzofwkimswvlsincu/Build/Products/Debug/TransportBaseTests.xctest/Contents/Resources/TransportBase_TransportBaseTests.bundle> (not yet loaded)))") is not equal to ("#FEFC78FF")
Here is the autogenerated code that my Swift Package Plugin creates:
#if canImport(SwiftUI)
import SwiftUI
import Foundation
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public extension Color {
static let banana = Color("Banana", bundle: .module)
static let alexsColor = Color("Alex's Color", bundle: .module)
static let reallyLongNameThatJustKeepsGoingOnAndOnAndOnAndOn = Color("really long name that just keeps going on and on and on and on", bundle: .module)
static let maximumPower = Color("Maximum Power", bundle: .module)
}
#endif
Does anyone know how to somehow instruct the bundle or the Color to load such that the comparison can be made correctly between the two colours?
I'm specifying the destination using the -destination option as follows:
-destination platform=macOS,arch=x86_64 and I receive the following warning (does not cause build failure, but still should be checked):
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:x86_64, id:00006000-001824163AD8801E }
{ platform:macOS, arch:x86_64, variant:Mac Catalyst, id:00006000-001824163AD8801E }
When I add variant=macOS, thus specifying -destination platform=macOS,arch=x86_64,variant=macOS, it then states that there isn't a destination that matches the specified criteria. What is the recommended way to specifically specify the platform to be a non-Mac Catalyst macOS destination?
I'm getting the following error messages from xcodebuild when building my swift package from the command line. It's not causing the build to fail or anything, but I'd rather be safer and fix this so that xcodebuild is happy. Is there any particular reason for this error popping up? My swift package contains three modules and each one is getting a similar error.
2023-02-04 23:58:32.550 xcodebuild[52859:2346817] [MT] IDEFileReferenceDebug: [Load] <IDEFileReference, 0x600000d67c00: name:Documentation.docc path:absolute:/Users/trevorhafner/Desktop/PERSONAL STUFF/App DEV/TransportBase/Sources/ColorBase/Documentation.docc> Failed to load container at path: /Users/trevorhafner/Desktop/PERSONAL STUFF/App DEV/TransportBase/Sources/ColorBase/Documentation.docc, Error: Error Domain=com.apple.dt.IDEContainerErrorDomain Code=6 "Cannot open "Documentation.docc" as a "Folder" because it is already open as a "Swift User Managed Package Folder"." UserInfo={NSLocalizedDescription=Cannot open "Documentation.docc" as a "Folder" because it is already open as a "Swift User Managed Package Folder".}
I have an NSOrderedSet of a custom class CDRoute which wraps and provides dynamic member lookup to a custom enumeration type called Route. The Route type has a property called precedence (Int16 type) and I would like to have a derived core data attribute where I can access the highest precedence value in the NSOrderedSet. This is relatively straightforward using Swift Computed Properties but I would like to incorporate this using core data since I've been having difficulty with changes being noticed. Due to the blatant lack of documentation surrounding how to construct a format string/woefully out of date documentation that describes how to do it in code but not how to format it in the Core Data model editor, I'm having a really difficult time with this. Is there any way to do something equivalent to the Swift map function ie
stops.routesServed.map({ $0.precedence }).@max
where stops.routesServed is the NSOrderedSet?
I'm trying to import some basic stop data for the trains in Chicago and there are two different custom Core Data types that I'm using to represent that data.
There are Station objects and Stop objects. The Station objects represent an entire station and the Stop objects represent a grouping of directions that exist within a Station.
The only relationships in the store are a many-one from Station to Stop (each station can have multiple groupings of directions in it, whereas each Stop can only belong to one station.)
I'm getting four main intermittent errors with my current code being related crashes (EXC_Bad Access, for example), heap corruption relating to "malloc_error_break", NSCFSet being mutated whilst being enumerated, and "CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000037006c0> , Objects should not be both modified and additional with userInfo of (null)" when I try to save the context.
Here is my current code that fetches the station data and performs a batch insert into Core Data.
static public func refreshData(for context: NSManagedObjectContext) async throws {
let url = URL(string: "https://data.cityofchicago.org/resource/8pix-ypme.json")!
let (data, _) = try await urlSession.data(from: url)
let decoder = JSONDecoder()
var stops = try decoder.decode([IntermediateStop].self, from: data)
var stations = stops
let relationships = stops
let stopsRequest = NSBatchInsertRequest(entity: Stop.entity(), managedObjectHandler: { managedObject in
guard !stops.isEmpty else {
return true
}
let stop = managedObject as! Stop
stop.update(from: stops.removeFirst())
return false
})
let stationsRequest = NSBatchInsertRequest(entity: Station.entity(), managedObjectHandler: { managedObject in
guard !stations.isEmpty else {
return true
}
let station = managedObject as! Station
station.update(using: stations.removeFirst())
return false
})
guard (try context.execute(stopsRequest) as! NSBatchInsertResult).result as! Bool else {
throw StationInitializationError.unsuccessfulInsertion
}
guard (try context.execute(stationsRequest) as! NSBatchInsertResult).result as! Bool else {
throw StationInitializationError.unsuccessfulInsertion
}
context.refreshAllObjects()
for stop in relationships {
let stationRequest: NSFetchRequest<Station> = Station.fetchRequest()
stationRequest.predicate = NSPredicate(format: "id = %@", argumentArray: [stop.stationid])
let stopRequest: NSFetchRequest<Stop> = Stop.fetchRequest()
stopRequest.predicate = NSPredicate(format: "id = %@", argumentArray: [stop.stopid])
let stationResults = try context.fetch(stationRequest)
let stopResults = try context.fetch(stopRequest)
stationResults.first!.addToStops(stopResults.first!)
}
try context.save()
}
When moving my working Core Data model to a swift package, the package/app combo build but the app crashes on launch. The debugger points to the @main attribute on my App struct (using SwiftUI) and prints the following messages in the console:
"CoreData: error: Failed to load model named StationData
Swift/UnsafeRawBufferPointer.swift:879: Fatal error: UnsafeRawBufferPointer with negative count
2022-03-09 20:46:29.156232-0600 Swift/UnsafeRawBufferPointer.swift:879: Fatal error: UnsafeRawBufferPointer with negative count"
I'm unsure as to what exactly is occurring here, especially since the model built and ran perfectly fine when it was a part of the app instead of the package.
When I run my app, SwiftUI occasionally flags a runtime error stating that "Modifying state during view update, this will cause undefined behavior." When looking into this error it points directly to the @main attribute on my struct that conforms to the App protocol. On closer inspection, it points to Core Data calling the coder initialiser for my StoredRoutes type (a type that conforms to NSSecureCoding and has a single instance property containing an array of Route (custom enumeration representing train routes)). I'm confused on how to proceed to fix the error.
When I run my app, Core Data gives this message
[general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x1dcf177d0) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
"'NSArray' (0x1dcf0cac8) [/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.
despite the fact that the custom value transformer that I have specifically allows StoredRoutes (custom type conforming to NSSecureCoding), NSArray and NSString.
The StoredRoutes type has an array of an enumeration Route which I use to keep track of the routes that are served by a station.
What am I missing here?
Value transformer code for reference:
import Foundation
final class StoredRoutesValueTransformer: NSSecureUnarchiveFromDataTransformer {
static var name = NSValueTransformerName(rawValue: "StoredRoutesValueTransformer")
override class func allowsReverseTransformation() -> Bool {
return true
}
override class func transformedValueClass() -> AnyClass {
return StoredRoutes.self
}
override class var allowedTopLevelClasses: [AnyClass] {
return [StoredRoutes.self, NSArray.self, NSString.self]
}
override func transformedValue(_ value: Any?) -> Any? {
guard let data = value as? Data else {
fatalError("Wrong data type: value must be of type Data. The type the value recieved was \(type(of: value)).")
}
return super.transformedValue(data)
}
override func reverseTransformedValue(_ value: Any?) -> Any? {
guard let storedRoutes = value as? StoredRoutes else {
fatalError("Wrong data type: value must be of type StoredRoutes. The type of the value recieved was \(type(of: value))")
}
return super.reverseTransformedValue(storedRoutes)
}
public static func register() {
let transformer = StoredRoutesValueTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
I have a view where the user can configure which train lines are shown on a map. I'm having an issue where the list row background is ignored for all of the cells which are selected.
Here is code that I am using:
struct MapConfigurator: View {
@Binding var routes: Set<Route>
var body: some View {
List(selection: $routes) {
Section(header: Text("Show")) {
ForEach(Route.allCases, id: \.self) { route in
Text(route.name)
.foregroundColor(route.textColor)
.listRowBackground(route.color)
.tag(route)
}
}
}
.navigationBarTitle("Configure Map")
.listStyle(GroupedListStyle())
.environment(\.editMode, .constant(.active))
}
}
struct MapConfigurator_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
MapConfigurator(routes: .constant([.red, .green, .blue]))
}
}
}
I'm thinking of using CoreML to create a Machine Learning Model for my iOS app. Are there any dangers in doing this (machine model getting too smart, etc)?
In my app I'm refreshing data and as part of that I need my Map view and a MapMarker on that Map view to move with it. The Map view is moving as expected, but the MapMarker is remaining where it is when the view is first presented.
struct MapView: View {
@Binding var train: Train
@Binding var region: MKCoordinateRegion
@Binding var marker: MapMarker
var body: some View {
Map(coordinateRegion: $region, interactionModes: .zoom, annotationItems: [train], annotationContent: { (_) in
return marker
})
.edgesIgnoringSafeArea(.bottom)
.navigationBarTitle("Train #\(train.runNumber)")
}
}
struct MapView_Previews: PreviewProvider {
@State static var train = sampleTrain1
@State static var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: sampleTrain1.position!.latitude, longitude: sampleTrain1.position!.longitude), latitudinalMeters: 1000, longitudinalMeters: 1000)
@State static var marker = MapMarker(coordinate: region.center)
static var previews: some View {
NavigationView {
MapView(train: $train, region: $region, marker: $marker)
}
}
}
I'm trying to have the region of a SwiftUI Map show a specific train. The compiler complains that the train property (see sample code below) is not available when the region property is being initialized. My solution to this is to set the location to the centre of the city, then set it to the train's location when the view appears.
struct MapView: View {
@Binding var train: Train
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: CLLocationDegrees(/* coordinate	presented as a Double literal */), longitude: CLLocationDegrees(/* coordinate	presented as a Double literal */)), latitudinalMeters: CLLocationDistance(1000), longitudinalMeters: CLLocationDistance(1000))
var body: some View {
Map(coordinateRegion: $region, interactionModes: .zoom, annotationItems: [train], annotationContent: { (train) in
return MapMarker.init(coordinate: CLLocationCoordinate2D(latitude: CLLocationDegrees(train.position!.latitude), longitude: CLLocationDegrees(train.position!.longitude)))
})
.edgesIgnoringSafeArea(.bottom)
.navigationBarTitle("Train #\(train.runNumber)")
.onAppear {
region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: CLLocationDegrees(train.position!.latitude), longitude: CLLocationDegrees(train.position!.longitude)), span: MKCoordinateSpan(latitudeDelta: CLLocationDegrees(1000), longitudeDelta: CLLocationDegrees(1000)))
}
}
}