Post

Replies

Boosts

Views

Activity

Reply to Having difficulty connecting relationships during a data import
The issues were occurring due to bad multithreading: Make sure that you are performing the code that you intend on the correct queue. static public func refreshData(for context: NSManagedObjectContext) async throws {         let relationships = try await StationFetcher().fetch(ignoresLowDataMode: false)         var stops = relationships         var stations = relationships                  try await context.perform {             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!)             }                          if context.hasChanges {                 try context.save()             }         }     }
Topic: Programming Languages SubTopic: Swift Tags:
Jan ’23
Reply to Core Data - Warns of unarchival of a type that is included in the permitted classes for the associated value transformer
Update: This error occurred since the custom class StoredRoutes was trying to decode an NSArray, use the methods for decoding an array instead. Older code: public init?(coder: NSCoder) {         if let nsArray = coder.decodeObject(of: NSArray.self, forKey: "routes") {             self.routes = []             for id in nsArray {                 self.routes.append(Route(rawValue: id as! String)!)             }         } else {             return nil         }     } New code that fixes this issue: public init?(coder: NSCoder) {         if let nsArray = coder.decodeArrayOfObjects(ofClass: NSString.self, forKey: "routes") {             self.routes = []             for id in nsArray {                 self.routes.append(Route(rawValue: id as String)!)             }         } else {             return nil         }     }
Jan ’23
Reply to Using Xcode with arbitrary Git repository
You can set up a repository using another provider by ticking the "Create Git repository on my Mac" option and then in the source control navigator (panel on left side, second tab), expand the category for the repository. Right click on "Remotes" and select "Add Existing Remote...". In the prompt that appears in the centre of the screen, you should be able to put in your server information and add the remote. If you already have a remote configured and everything, Xcode should be able to just see the git repository and recognise the existence of the remotes, so pushing, pulling, committing and other simpler git operations should be available from the source control menu.
Jan ’23
Reply to SwiftUI modifying state warning - pointing to @main
Here's my custom StoredRoutes type: import Foundation final class StoredRoutes: NSObject, NSSecureCoding {     static var supportsSecureCoding: Bool = true     func encode(with coder: NSCoder) {         var routeids: [NSString] = []         for route in routes {             routeids.append(NSString(string: route.rawValue))         }         coder.encode(NSArray(array: routeids), forKey: "routes")     }     init?(coder: NSCoder) {         if let nsArray = coder.decodeObject(of: NSArray.self, forKey: "routes") {             self.routes = []             for id in nsArray {                 self.routes.append(Route(rawValue: id as! String)!)             }         } else {             return nil         }     }     var routes: [Route]     required init(routes: [Route]) {         self.routes = routes     } } and my value transformer: 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)     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Using an @EnvironmentObject Breaks Xcode Previews
I would recommend trying to put the .environmentObject modifier on the view that you're previewing or the top level group if there are two or more of them. In the modifier you'll have to specify an instance of your environment object. Based on your code sample, you could probably just put SettingsData() in the argument for the modifier to satisfy it. Here's an example of the preview code that might fit your needs (one view) static var previews: some View { SomeView() .environmentObject(SettingsData()) } or more than one view static var previews: some View { Group { SomeView() AnotherView() // Any other views that would be placed here } .environmentObject(SettingsData()) }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to "Sorry, you can’t enroll at this time." when enrolling.
You have to be at least 18 years old to enrol in the Apple Developer Program yourself. There however, I believe, exists a way for you to enrol otherwise. If I am not mistaken, you can enrol using an Apple ID of someone who is over the age of 18 (parent/guardian, for example) and use their account to access the services that the Apple Developer Program provides. I would recommend double checking with Apple Developer Support before continuing.
Jan ’22
Reply to How to filter data from an api, and how to use userdefaults to load and save data?
I would recommend using Core Data instead of UserDefaults, since UserDefaults is designed for smaller scale things like device settings for an app for example. Core Data can easily handle the movie metadata. As for the thumbnail, you can store that too but its a little more complicated. I'm not entirely sure how to do it off the top of my head, but there should be a way to store it. In terms of integrating Core Data with your user interface, you can use the NSFetchedResultsController to connect your UI where you would use the values from the fetched results controller to return as part of the UIKit implementation. I would also recommend that you use Swift's new concurrency support if you're project has an iOS/iPadOS development target of iOS/iPadOS 15.0 or later. It'll make it more difficult to make mistakes such as leaving the caller of your methods hanging by not calling the completion handler by accident.
Topic: UI Frameworks SubTopic: UIKit Tags:
Dec ’21
Reply to SwiftUi basic questions
As for your questions: SwiftUI is a UI framework that uses a declarative syntax where you basically tell the framework what you want and the framework figures out how to do it. (AppKit/UIKit/WatchKit use an imperative syntax where you tell the framework what to do) SwiftUI user interfaces can be made using code or using Xcode Previews (you can switch as frequently as you like during the development process, whereas with AppKit/UIKit/WatchKit you have to use Interface Builder (.storyboard files) or code for the entirety of the development process.) SwiftUI does not use storyboards, and I believe it does support Drag and Drop interfaces, but I am not sure about this one. SwiftUI can be integrated with AppKit/UIKit/WatchKit: In order to integrate SwiftUI into one of the other three frameworks, you use a hosting controller and can put a SwiftUI view in it. It seems to be a storyboard reference but for SwiftUI views. For integrating AppKit/UIKit/WatchKit into SwiftUI there are representable protocols (Example: UIViewRepresentable, UIViewControllerRepresentable) where you can make and update your AppKit/UIKit/WatchKit views for SwiftUI. Go through the Tutorials and you will get all the answer you need. I found the tutorials very helpful when learning SwiftUI. There is a section where you integrate with UIKit in order to put a map into the example app.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’20
Reply to How can I make request to an API and then create a view in SwiftUI?
I would recommend using a Combine publisher and then make a class that interfaces with the publisher. You can get a combine publisher from URLSession and then use the built in operators or make some of your own in order to transform the data that you receive to make it easier for SwiftUI to read it. The class that interfaces with the publisher can receive all of its messages and be connected to any SwiftUI view using the @StateObject, @ObservedObject or @EnvironmentObject property wrappers. Make sure that the class interfacing between your publisher and SwiftUI conforms to the ObservableObject protocol (or else it won't work with the aforementioned property wrappers.) I find that the built in operators in Combine work well enough so that creating an operator is usually not required.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’20
Reply to is it possible to have SwiftUI single code base for iOS14 and 13?
When you create a new iOS App in Xcode, it should have an option for "UIKit AppDelegate" or something like that. That will create a new project with an AppDelegate and a SceneDelegate. You should then be able to set the minimum deployment target to iOS 13. (Note: Only do this for new projects. For older projects, you can make a new project and copy the AppDelegate.swift and SceneDelegate.swift file from the newer project to the older project and delete the file containing the struct conforming to the App protocol. You can also manually make an AppDelegate.swift and SceneDelegate.swift file, though I am unsure on how one would do that exactly.)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’20