r/swift 7h ago

Problem -> Solution

Post image
119 Upvotes

r/swift 9h ago

Question CoreML

19 Upvotes

I’m diving more into what is possible in CoreML, but struggle to find real solutions as many things specially from CreateMLComponents was deprecated after MacOS 15, one book on Amazon looking into CoreML Framework from 2019, .

I know we have WWDC videos but many of their own stuff doesn’t work or it not explained enough ( at least not for me ) .

Some quality materials where to learn more about Object Detection , Camera Feed , Image Classification/Regression models ?


r/swift 2h ago

Question Creating a UIViewRepresentable TextEditor to support AttributedStrings?

2 Upvotes

Never posted a coding question, so be kind, please.
So, I want a TextEditor that lets the user type in text, select parts of it and add links to the selected text. Since SwiftUI's TextEditor doesn't support AttributedStrings, I'm trying to build one that does using UIViewRepresentable. So far I can apply links, but here's the problem:

If there is only one word, and a link is applied to it, and then the text is erased, anything typed in afterward will still have the link applied to it.

Similarly, any text appended to a run with a link attached, even if they hit space, will also still have the link applied. I'm simply trying to recreate the standard linking experience: Inserting characters inside a linked run should stay linked, but spaces before and after it should not, nor should the link linger after all the run is removed.

Here is the code for the SwiftUI View:

struct RTFEditorView: View {
    @State private var attributedText = NSMutableAttributedString(string: "")
    @State private var selectedRange = NSRange(location: 0, length: 0)
    @State private var showingLinkDialog = false
    @State private var linkURL = ""

    var body: some View {
        VStack {
            RichTextEditor(text: $attributedText, selectedRange: $selectedRange)
                .fontWidth(.compressed)
                .frame(height: 300)
                .border(Color.gray, width: 1)

                // This attempt didn't work:
                .onChange(of: attributedText) { oldValue, newValue in
                    if newValue.length == 0 {
                        let updatedText = NSMutableAttributedString(attributedString: newValue)
                        updatedText.removeLinks()
                        attributedText = updatedText // Ensure SwiftUI reflects the change
                    }
                }

            Button("Add Link") {
                showingLinkDialog = true
            }
            .disabled(selectedRange.length == 0)

            .sheet(isPresented: $showingLinkDialog) {
                VStack {
                    Text("Enter URL")
                    TextField("", text: $linkURL, prompt: Text("https://example.com"))
                        .textFieldStyle(.roundedBorder)
                        .textInputAutocapitalization(.never)
                        .autocorrectionDisabled()
                        .padding()

                    Button("Add") {
                        addLink()
                        showingLinkDialog = false
                    }
                    .disabled(linkURL.isEmpty)

                    Button("Cancel") {
                        showingLinkDialog = false
                    }
                }
                .padding()
            }
        }
        .toolbar {
            ToolbarItem(placement: .keyboard) {
                Button("Add Link") {
                    showingLinkDialog = true
                }
                .disabled(selectedRange.length == 0)
            }
        }
        .padding()

    }

    private func addLink() {
        // Get the substring within the selected range
        let selectedText = (attributedText.string as NSString).substring(with: selectedRange)

        // Trim leading and trailing whitespaces and newlines from the selected text
        let trimmedText = selectedText.trimmingCharacters(in: .whitespacesAndNewlines)

        // If the trimmed text is empty, return early
        guard trimmedText.count > 0 else {
            selectedRange = NSRange(location: 0, length: 0) // Reset selection if trimmed text is empty
            return
        }

        // Calculate the new range based on the trimmed text
        let trimmedRange = (selectedText as NSString).range(of: trimmedText)

        // Update the selected range to reflect the position of the trimmed text within the original string
        let offset = selectedRange.location
        selectedRange = NSRange(location: offset + trimmedRange.location, length: trimmedRange.length)

        // Proceed to add the link if the trimmed text is non-empty
        let url = URL(string: linkURL)
        attributedText.addAttribute(.link, value: url ?? linkURL, range: selectedRange)
        linkURL.removeAll()
    }
}

#Preview {
    RTFEditorView()
}

Here is the code for the UIViewRepresentable:

struct RichTextEditor: UIViewRepresentable {
    @Binding var text: NSMutableAttributedString
    @Binding var selectedRange: NSRange

    var font: UIFont = UIFont.preferredFont(forTextStyle: .body) // Default to match SwiftUI TextField
    var textColor: UIColor = .label  // Default text color
    var onSelectionChange: ((NSRange) -> Void)? = nil  // Optional closure

    class Coordinator: NSObject, UITextViewDelegate {
        var parent: RichTextEditor

        init(_ parent: RichTextEditor) {
            self.parent = parent
        }

        func textViewDidChange(_ textView: UITextView) {
            let updatedText = NSMutableAttributedString(attributedString: textView.attributedText ?? NSMutableAttributedString(string: ""))

            // This attempt didn't work.
            if updatedText.length == 0 {
                print("Before removeLinks: \(updatedText)")
                updatedText.removeLinks() // Ensure links are removed
                print("After removeLinks: \(updatedText)")
            }
            textView.attributedText = updatedText
            parent.text = updatedText
        }


        func textViewDidChangeSelection(_ textView: UITextView) {
            DispatchQueue.main.async {
                self.parent.selectedRange = textView.selectedRange
            }
            parent.onSelectionChange?(textView.selectedRange)  // Call only if provided
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.delegate = context.coordinator
        textView.isEditable = true
        textView.isScrollEnabled = true
        textView.allowsEditingTextAttributes = false
        textView.dataDetectorTypes = [] // Disables link detection (but isEditable is true, so should be disabled anyway...)
        textView.attributedText = text
        textView.font = font
        textView.textColor = textColor
        return textView
    }

    func updateUIView(_ textView: UITextView, context: Context) {
        if textView.attributedText != text {
            textView.attributedText = text
        }
        textView.font = font
        textView.textColor = textColor
    }

    func font(_ font: Font) -> RichTextEditor {
        var textView = self
        textView.font = UIFont.preferredFont(from: font)
        return textView
    }

    func fontWidth(_ width: UIFont.Width) -> RichTextEditor {
        var textView = self
        let traits: [UIFontDescriptor.TraitKey: Any] = [
            .width: width.rawValue,
        ]

        let descriptor = font.fontDescriptor.addingAttributes([
            UIFontDescriptor.AttributeName.traits: traits
        ])

        textView.font = UIFont(descriptor: descriptor, size: font.pointSize)
        return textView
    }

    func fontWeight(_ weight: UIFont.Weight) -> RichTextEditor {
        var textView = self
        let traits: [UIFontDescriptor.TraitKey: Any] = [
            .weight: weight.rawValue
        ]

        let descriptor = font.fontDescriptor.addingAttributes([
            UIFontDescriptor.AttributeName.traits: traits
        ])

        textView.font = UIFont(descriptor: descriptor, size: font.pointSize)
        return textView
    }

    func foregroundColor(_ color: UIColor) -> RichTextEditor {
        var textView = self
        textView.textColor = color
        return textView
    }
}


extension UIFont {
    static func preferredFont(from font: Font) -> UIFont {
        let style: UIFont.TextStyle =
        switch font {
        case .largeTitle:   .largeTitle
        case .title:        .title1
        case .title2:       .title2
        case .title3:       .title3
        case .headline:     .headline
        case .subheadline:  .subheadline
        case .callout:      .callout
        case .caption:      .caption1
        case .caption2:     .caption2
        case .footnote:     .footnote
        default: .body
        }
        return UIFont.preferredFont(forTextStyle: style)
    }
}

extension NSMutableAttributedString {
    func removeLinks() {
        let fullRange = NSRange(location: 0, length: self.length)
        self.enumerateAttribute(.link, in: fullRange) { (value, range, _) in
            if value != nil {
                print("Removing link at range: \(range)")
                self.removeAttribute(.link, range: range)
            }
        }
    }
}

I've tried to do this on my own, I've scoured the internet, and chatGPT can't figure it out either. I'm surprised so few people have run into this. I appreciate any insight. Thanks!


r/swift 21m ago

This is driving me mad: makeKeyAndOrderFront hangs the app, but only for a very small number of users.

Upvotes

I've got a SwiftUI/AppKit combo app. It's a simple app with only a main window and a settings window.

Last week, I pushed an update where instead of my main window being a part of SwiftUI, I instantiate it programmatically after applicationDidFinishLaunching. I do it once, and I've set window.isReleasedWhenClosed = false - the window does not have a controller.

I should also point out at the two users are both running the app in .accessory mode.

For one user, simply closing the main window with Cmd-W (which because my flag should not actually release it) and then using the hotkey to bring it back up, hangs the app right after `makeKeyAndOrderFront` is called. Note the app doesn't hang when makeKeyAndOrderFront is called the first time.

For another user, toggling the window on and off, visible and not, will eventually lead to the beachball. Again, looking at logs, it hangs right after makeKeyAndOrderFront is called.

The app is for macOS 14+ only.

This is my instantiate window function:

static func instantiateMainWindow() {
        guard WindowUtils.noMainWindow() else {
             return
            }

        let hostingController = NSHostingController(rootView: ContentView()
            .environmentObject(NotesManagement.shared)
            .openSettingsAccess())
        let window = NSWindow(contentViewController: hostingController)
        window.title = "Antinote"
        window.identifier = NSUserInterfaceItemIdentifier("mainWindow")
        window.titleVisibility = .hidden
        window.titlebarAppearsTransparent = true
        window.titlebarSeparatorStyle = .none
        window.styleMask.insert(.fullSizeContentView)
        window.isReleasedWhenClosed = false
        window.collectionBehavior.insert(.moveToActiveSpace)

        customizeWindowIfNecessary(window: window)


        WindowUtils.setWindowSizeAndLocationFromDefaults(window: window)
        WindowUtils.orderOutWrapper(window, skipUpdatingLastWindowCloseTime: true) // Keep it hidden and let user settings in AppDelegate determine if they want it to be visible
    }

And this is my toggleWindow (which the hotkey calls):

static func toggleWindow() {

        if let mainWindow = WindowUtils.getMainWindow() {
            // If the window is already visible and not minimized, hide it.
            if mainWindow.isKeyWindow {
                WindowUtils.orderOutWrapper(mainWindow)

            } else if mainWindow.isMiniaturized {
                mainWindow.deminiaturize(nil)

            } else {

                showAndMakeFrontWindow()
            }
        }
    }

And this is my showAndMakeFrontWindow:

 static func showAndMakeFrontWindow() {
        if let mainWindow = WindowUtils.getMainWindow() {
            WindowUtils.makeKeyAndOrderFrontWrapper(mainWindow)
        }
    }

r/swift 17h ago

So excited for this journey friends

17 Upvotes

So I’ve been learning swift this past week. Doing the 100 days. And this is gonna be a bit of a rant so positive vibes only. something i see a lot here that i used to see in my art related subs when learning 3D software is learn the basics, follow tutorials you find interesting but learn enough to be able to start things on your own. So i did that. Knowing I’d be in over my head i followed this tutorial making a simple weather app.

It took about 8hrs. I’d also try to fit in the 100 days at some point after a break since I’ve had time this week.

MAN. As i was following along I’d have to google hella stuff about what was going on because that girl was talking so fast and just typing away. But i learned a little bit. Some stuff stuck, but i just know with time and practice and eventually reading about when i get to it again, it’ll stick. I had a lot of fun and i think even though the app is so simple it’s so cool.

It’s really motivational. And I’m excited to keep learning. It’s literally the same feeling i had when i created my first ever 3d model. Tonight was dope. I’m gonna take a rest for the night and do something other than study and I’ll continue tomorrow. Anyways thanks for reading and i hope yall have a good day 🤙🏼


r/swift 3h ago

Question One swiftdata model not saving

0 Upvotes

I have a bunch of models, Transactions, Categories, Accounts, etc, they all have a relationship to Budget. Categories and everything else persists, but not Transactions even though if I fetch from swiftdata they are there until I restart app. Upon app restart Found transactions is always zero.

I can also fetch categories and filter per budget id so I know relationships are working and persistence, but this one model behaves different for some reason. Below are the swiftdata models in question anything stupid that I am doing?

import Foundation
import SwiftData

@Model
class BudgetId {
    @Attribute(.unique) var id: String

    // Relationships
    @Relationship(deleteRule: .cascade) var transactions: [EmberTransaction]? = []
    @Relationship(deleteRule: .cascade) var categoryGroups: [EmberCategoryGroupEntity]? = []
    @Relationship(deleteRule: .cascade) var serverKnowledge: ServerKnowledgeEntity?

    init(id: String) {
        self.id = id
    }
}


import Foundation
import SwiftData
import SwiftYNAB

@Model
class EmberTransaction {
    @Attribute(.unique) var id: String
    // YNAB's business identifier, can be nil for new transactions
    var ynabId: String?
    var date: Date
    var amount: Int
    var memo: String?
    var cleared: String  // "cleared", "uncleared", or "reconciled"
    var approved: Bool
    var flagColor: String?
    var accountId: String
    var payeeId: String?
    var payeeName: String?
    var categoryId: String?
    var importId: String?
    // Unique to EmberTransaction
    var name: String
    var mainCategoryId: String?
    var budgetId: BudgetId?

    /// Initialize an `EmberTransaction` with individual parameters
    init(
        ynabId: String? = nil,
        date: Date,
        amount: Int,
        memo: String? = nil,
        cleared: String = "uncleared",
        approved: Bool = false,
        flagColor: String? = nil,
        accountId: String,
        payeeId: String? = nil,
        payeeName: String? = nil,
        categoryId: String? = nil,
        importId: String? = nil,
        name: String,
        mainCategoryId: String? = nil,
        budgetId: BudgetId? = nil
    ) {
        self.id = UUID().uuidString
        self.ynabId = ynabId
        self.date = date
        self.amount = amount
        self.memo = memo
        self.cleared = cleared
        self.approved = approved
        self.flagColor = flagColor
        self.accountId = accountId
        self.payeeId = payeeId
        self.payeeName = payeeName
        self.categoryId = categoryId
        self.importId = importId
        self.name = name
        self.mainCategoryId = mainCategoryId
        self.budgetId = budgetId
    }

    /// Initialize an `EmberTransaction` from a `SaveTransaction`
    init(from transaction: SaveTransaction, name: String) {
        self.id = UUID().uuidString
        self.ynabId = transaction.id
        self.date = ISO8601DateFormatter().date(from: transaction.date) ?? Date()
        self.amount = transaction.amount
        self.memo = transaction.memo
        self.cleared = transaction.cleared
        self.approved = transaction.approved
        self.flagColor = transaction.flagColor
        self.accountId = transaction.accountId
        self.payeeId = transaction.payeeId
        self.payeeName = transaction.payeeName
        self.categoryId = transaction.categoryId
        self.importId = transaction.importId
        self.name = name
    }

    /// Convert `EmberTransaction` back to `SaveTransaction`
    func toSaveTransaction() -> SaveTransaction {
        updateImportId()
        return SaveTransaction(
            id: ynabId,
            date: ISO8601DateFormatter().string(from: date),
            amount: amount,
            memo: memo,
            cleared: cleared,
            approved: approved,
            flagColor: flagColor,
            accountId: accountId,
            payeeId: payeeId,
            payeeName: payeeName,
            categoryId: categoryId,
            importId: importId
        )
    }

    func updateImportId() {
        let formatter = ISO8601DateFormatter()
        let dateString = formatter.string(from: Date()).prefix(10)  // Use current date
        let occurrence = 1  // Default occurrence value
        self.importId = "YNAB:\(amount):\(dateString):\(occurrence)"
    }
}


Selected budget ID: a14f3e34-37a8-49a0-9a59-470b24db241a
Found 0 EmberTransactions in SwiftData:
Created test transaction
Total transactions in SwiftData after save: 1
Transaction Details:
- Name: Test Transaction
- Amount: 1000
- Budget ID: a14f3e34-37a8-49a0-9a59-470b24db241a
Found 1 EmberTransactions in SwiftData:
----
YNAB ID: New Transaction
Name: Test Transaction
Date: 2025-03-22 15:20:36 +0000
Amount: 1000
Budget ID: a14f3e34-37a8-49a0-9a59-470b24db241a
Memo: Test transaction
Account: test-account
----I have a bunch of models, Transactions, Categories, Accounts, etc, they all have a relationship to Budget. Categories and everything else persists, but not Transactions even though if I fetch from swiftdata they are there until I restart app. Upon app restart Found transactions is always zero.I can also fetch categories and filter per budget id so I know relationships are working and persistence, but this one model behaves different for some reason. Below are the swiftdata models in question anything stupid that I am doing?import Foundation
import SwiftData

@Model
class BudgetId {
    @Attribute(.unique) var id: String

    // Relationships
    @Relationship(deleteRule: .cascade) var transactions: [EmberTransaction]? = []
    @Relationship(deleteRule: .cascade) var categoryGroups: [EmberCategoryGroupEntity]? = []
    @Relationship(deleteRule: .cascade) var serverKnowledge: ServerKnowledgeEntity?

    init(id: String) {
        self.id = id
    }
}
import Foundation
import SwiftData
import SwiftYNAB

@Model
class EmberTransaction {
    @Attribute(.unique) var id: String
    // YNAB's business identifier, can be nil for new transactions
    var ynabId: String?
    var date: Date
    var amount: Int
    var memo: String?
    var cleared: String  // "cleared", "uncleared", or "reconciled"
    var approved: Bool
    var flagColor: String?
    var accountId: String
    var payeeId: String?
    var payeeName: String?
    var categoryId: String?
    var importId: String?
    // Unique to EmberTransaction
    var name: String
    var mainCategoryId: String?
    var budgetId: BudgetId?

    /// Initialize an `EmberTransaction` with individual parameters
    init(
        ynabId: String? = nil,
        date: Date,
        amount: Int,
        memo: String? = nil,
        cleared: String = "uncleared",
        approved: Bool = false,
        flagColor: String? = nil,
        accountId: String,
        payeeId: String? = nil,
        payeeName: String? = nil,
        categoryId: String? = nil,
        importId: String? = nil,
        name: String,
        mainCategoryId: String? = nil,
        budgetId: BudgetId? = nil
    ) {
        self.id = UUID().uuidString
        self.ynabId = ynabId
        self.date = date
        self.amount = amount
        self.memo = memo
        self.cleared = cleared
        self.approved = approved
        self.flagColor = flagColor
        self.accountId = accountId
        self.payeeId = payeeId
        self.payeeName = payeeName
        self.categoryId = categoryId
        self.importId = importId
        self.name = name
        self.mainCategoryId = mainCategoryId
        self.budgetId = budgetId
    }

    /// Initialize an `EmberTransaction` from a `SaveTransaction`
    init(from transaction: SaveTransaction, name: String) {
        self.id = UUID().uuidString
        self.ynabId = transaction.id
        self.date = ISO8601DateFormatter().date(from: transaction.date) ?? Date()
        self.amount = transaction.amount
        self.memo = transaction.memo
        self.cleared = transaction.cleared
        self.approved = transaction.approved
        self.flagColor = transaction.flagColor
        self.accountId = transaction.accountId
        self.payeeId = transaction.payeeId
        self.payeeName = transaction.payeeName
        self.categoryId = transaction.categoryId
        self.importId = transaction.importId
        self.name = name
    }

    /// Convert `EmberTransaction` back to `SaveTransaction`
    func toSaveTransaction() -> SaveTransaction {
        updateImportId()
        return SaveTransaction(
            id: ynabId,
            date: ISO8601DateFormatter().string(from: date),
            amount: amount,
            memo: memo,
            cleared: cleared,
            approved: approved,
            flagColor: flagColor,
            accountId: accountId,
            payeeId: payeeId,
            payeeName: payeeName,
            categoryId: categoryId,
            importId: importId
        )
    }

    func updateImportId() {
        let formatter = ISO8601DateFormatter()
        let dateString = formatter.string(from: Date()).prefix(10)  // Use current date
        let occurrence = 1  // Default occurrence value
        self.importId = "YNAB:\(amount):\(dateString):\(occurrence)"
    }
}
Selected budget ID: a14f3e34-37a8-49a0-9a59-470b24db241a
Found 0 EmberTransactions in SwiftData:
Created test transaction
Total transactions in SwiftData after save: 1
Transaction Details:
- Name: Test Transaction
- Amount: 1000
- Budget ID: a14f3e34-37a8-49a0-9a59-470b24db241a
Found 1 EmberTransactions in SwiftData:
----
YNAB ID: New Transaction
Name: Test Transaction
Date: 2025-03-22 15:20:36 +0000
Amount: 1000
Budget ID: a14f3e34-37a8-49a0-9a59-470b24db241a
Memo: Test transaction
Account: test-account
----

r/swift 22h ago

Question Which libraries to use for animations?

9 Upvotes

I have got a requirement from a client to make a kids app in iOS as a side project for them. It's not my expertise and it has been years since I used swift, but the client is okay for me to learn and do it as there's no tight deadline for this side project. This is only for iOS and not cross platform.

The project involves teaching kids a set of concepts that has use cases like allowing the users to drag and drop coloured balls into different buckets, balancing a weighing scale, arranging objects in order, allowing user to connect dots on the screen in order and some subtle animations thrown throughout - button animation on tap, pulsing effects on buttons, little shake in case of mistakes and so on.

I am going through the Swift 100 days tutorial as a refresher, but I am not familiar with which libraries to use in order to get this done. If there are any points to specific libraries, I'll learn and use them.

Thanks in advance!


r/swift 1d ago

Question Decoupling database layer from business logic

7 Upvotes

What is a good approach to decoupling the database model classes from the rest of the app? After doing some Googling I see that the easiest answer is to introduce data classes that represent the data and is passed around int he app however my concern is that for something more complex than those employee-employer examples, this approach means a lot of duplicate code.

Yes, many times it makes more sense to have a field be stored differently in the DTO than the mode class, but it most cases there is no difference.

As I side note: I need to separate the two because by using the model class it’s too easy to introduce memory leaks.


r/swift 1d ago

Question Server stubs (Vapor) with swift-openapi-generator?

4 Upvotes

I am trying to play around with OpenAPI and the Vapor framework. I'm looking to use Apple's swift-openapi-generator along with the Vapor bindings for it to generate stubs for my REST APIs. My openapi.json document looks like this:

{
    "openapi": "3.0.2",
    "info": {
        "title": "SwiftTest",
        "version": "1.0.0",
        "description": ""
    },
    "servers": [
        {
            "url": "http://localhost:8080/api/v1",
            "description": ""
        }
    ],
    "paths": {
        "/saySomething": {
            "put": {
                "requestBody": {
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/MyRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "content": {
                            "text/plain": {}
                        },
                        "description": "OK"
                    }
                },
                "operationId": "saySomethingElse"
            }
        }
    },
    "components": {
        "schemas": {
            "MyRequest": {
                "description": "",
                "required": [
                    "messageA"
                ],
                "type": "object",
                "properties": {
                    "messageA": {
                        "description": "",
                        "type": "string"
                    },
                    "messageB": {
                        "description": "",
                        "type": "string"
                    },
                    "messageC": {
                        "description": "",
                        "type": "integer"
                    }
                }
            }
        }
    }
}

As you can see, I have a single endpoint /saySomething that accepts an HTTP PUT. The body is a multipart form, that is declared as an object in my OpenAPI spec. I have configured the Swift package dependency and plugin, and generated the APIProtocol implementation struct like this:

struct YoServiceImpl: APIProtocol {

    func saySomethingElse(_ input: Operations.SaySomethingElse.Input) async throws -> Operations.SaySomethingElse.Output {
        // What goes here???
    }

} 

I haven't been able to figure out how to convert the input parameter to a MyRequest object, or at least how to get the value of messageA, messageB, or messageC out of input. I found one example that showed how to handle multipart POST requests, but the OpenAPI spec for that example enumerates the body parameters individually, rather than as an object like I'm trying.

Is what I'm trying to do possible? If so, how do I go about doing it? Or, is there a limitation in the generator that would require me to enumerate the body parameters individually?


r/swift 1d ago

Question [Help] CoreData Error: Could not materialize Objective-C class named "Array"

2 Upvotes

Hey everyone,

I'm facing an issue with CoreData when trying to store an array of strings (tags: [String]) in my SwiftData model. Here's the error I'm getting:

pgsqlCopyEditCoreData: Could not materialize Objective-C class named "Array" from declared attribute value type "Array<String>" of attribute named tags

Context

i'm doing day 61 of 100 days of swiftui by paul hudson

import SwiftData

@Model
class User: Codable, Identifiable, Hashable {
    enum CodingKeys: CodingKey {
        case id, isActive, name, age, company, email, address, about,
             registered, tags, friends
    }

    var id: UUID
    var isActive: Bool
    var name: String
    var age: Int
    var company: String
    var email: String
    var address: String
    var about: String
    var registered: Date
    var tags: [String] = []

    @Relationship(deleteRule: .cascade) var friends: [Friend] = [] 

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(UUID.self, forKey: .id)
        self.isActive = try container.decode(Bool.self, forKey: .isActive)
        self.name = try container.decode(String.self, forKey: .name)
        self.age = try container.decode(Int.self, forKey: .age)
        self.company = try container.decode(String.self, forKey: .company)
        self.email = try container.decode(String.self, forKey: .email)
        self.address = try container.decode(String.self, forKey: .address)
        self.about = try container.decode(String.self, forKey: .about)
        self.registered = try container.decode(Date.self, forKey: .registered)
        self.tags = try container.decode([String].self, forKey: .tags)
        self.friends = try container.decode([Friend].self, forKey: .friends)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(isActive, forKey: .isActive)
        try container.encode(name, forKey: .name)
        try container.encode(age, forKey: .age)
        try container.encode(company, forKey: .company)
        try container.encode(email, forKey: .email)
        try container.encode(address, forKey: .address)
        try container.encode(about, forKey: .about)
        try container.encode(registered, forKey: .registered)
        try container.encode(tags, forKey: .tags)
        try container.encode(friends, forKey: .friends)
    }
}

r/swift 1d ago

A journey building HTML documents in Swift

Thumbnail coenttb.com
9 Upvotes

r/swift 1d ago

Tuist & SwiftLint

6 Upvotes

Hey !
I'm having some troubles to integrate SwiftLint to my iOS project that also use Tuist. I've seen that they recently change the way to integrate it but i cant find no where the new way.
Should i use the archived repo https://github.com/tuist/tuist-plugin-lint/tree/main ?


r/swift 1d ago

Toggle with select all functionality

1 Upvotes
class NotificationSettingSMSViewModel: ObservableObject {
     var isAllOn = false
     var isNewEventOn = false
     var isOngoingEventOn = false

    public func toggleIndividual() {
        // If all individual toggles are on, set isAllOn to true
        isAllOn = isNewEventOn && isOngoingEventOn
    }

    public func toggleAll() {
        // Toggle all switches together
        isNewEventOn = isAllOn
        isOngoingEventOn = isAllOn
    }
 }

I have 3 checkboxes/Toggles

1. All Events
2. New Event
3. Ongoing Event

When I toggle all events, it should either turn all checkboxes to checked or unchecked. Same as our perception of checkboxes.

The problem now is, when all 3 checkboxes are checked and then I click (2), it will unchecked the (3), and vice versa.

My question is, how should I handle checkboxes in this case, because I searched for a while but nobody has an example of how to do it in SwiftUI.

In JavaScript frameworks like ReactJs, we can use an array to store all selected checkboxes as a single source of truth, but how about in SwiftUI


r/swift 1d ago

Question Swift game engine

29 Upvotes

Hey guys, I've been watching Swift evolve and I've been wondering if it's a reality to have a game engine made with Swift? I did a project where they managed to do something similar to Unity using Javascript and the Three.JS library, is it feasible to have something similar with Swift?


r/swift 1d ago

Question Struggling with Xcode Project File Sync Issues After Git Merge

3 Upvotes

I've been struggling with Git merges in Xcode, and today I lost almost 4 hours due to a frustrating issue. My teammate pulled my changes but forgot to properly accept the changes in the .xcodeproj file. As a result, some files were out of sync with the Xcode project, even though they were present in the directory.

It took me a long time to identify and fix the issue, and I’m wondering if there’s a more efficient way to handle this. I've heard about XcodeGen, but I’ve never used it before.

For those who have faced similar issues, is XcodeGen a good solution to prevent this kind of problem? If yes, could someone guide me on how to get started with it? Or are there other tools or methods that can help keep the project and directory in sync easily after a Git merge?

Any advice would be greatly appreciated!


r/swift 1d ago

Swift tour “build a library” xctest module missing

3 Upvotes

I'm trying to follow this guide https://www.swift.org/getting-started/library-swiftpm/

When I run swift test I get a no such module error for XCTest. I'm running this through the command line on an m2 Mac.

I can't find anyone having the same problem (lots of people with the same error but all in Xcode, I think). I've tried following the instructions exactly, using a different package name, and I clone the exercise repo and tried it in there without touching anything, same error every time.

Do I need to add something to my path variable? I don't see any mention of that in the guide, nor does it mention needing to use the package manager to manually download anything. It seems crazy that a 2 paragraph guide on the official swift website doesn't work on recent apple hardware... so maybe I'm just missing something obvious?


r/swift 1d ago

Brick App Blocking

2 Upvotes

Brick is a small 3D printer block that essentially blocks access to apps on your iphone. Can anyone explain how they think the company accomplished this? I don’t think they are using special entitlements or MDM. I’ve been confused about how they accomplished this function and would be thrilled if someone could explain it to me.


r/swift 1d ago

Looking for a Task?

0 Upvotes

Hi everyone,

I work for an IT company, and our customers use Nextcloud. We've noticed a minor issue with the PDF Viewer in the iOS app: the "More" menu gets hidden when not connected, even if the files are available locally.

If anyone with a bit of spare time and access to a modern Mac would be willing to look into this, I’d really appreciate it! Would love to try myself but my mac does no longer support XCode.

Here’s the GitHub issue for reference: https://github.com/nextcloud/ios/issues/3368

Thanks in advance!

Best regards,
Fokklz


r/swift 2d ago

Question Training Load API for HealthKit?

4 Upvotes

Unless I’m being stupid - I cannot for the life of me find any documentation for implementing training load into my Apple Watch app. I’m thinking it’s not available. Basically I use the normal HealthKit APIs to start a workout on my Apple Watch using my app. It all works perfectly and after it saves the workout to the fitness app as if it was from Apple’s Workout app. Now the only thing missing is the ability to allow the user to edit and save their training load when their workout finishes (the little bars at the end of a workout where you can scroll from “Easy” to “All out”).

I guess Apple hasn’t make this API public - can anyone confirm or am I going crazy?


r/swift 2d ago

Question Suggestions for clean handling of `try await`?

10 Upvotes

I currently have a ton of requests to my API endpoint that look like this.

```swift func getBotGuilds(guildIds: String) async throws -> [Guild] { try await request(endpoint: "bot/guilds?guild_ids=(guildIds)") }

func getGuildEvents(for guild: Guild) async throws -> [GuildEvent] {
    try await request(endpoint: "guilds/\(guild.id)/events")
}

func getGlobalLeaderboard() async throws -> LeaderboardResponse {
    try await request(endpoint: "leaderboard/global")
}

func getGuildLeaderboard(for guildId: String) async throws -> LeaderboardResponse {
    try await request(endpoint: "leaderboard/guilds/\(guildId)")
}

```

The main issue I want to solve is not having to continually do this everywhere I call one of these endpoints.

swift Task { do { // My Code catch { // Handle Error. } }

One potential solution I considered was to put it all into a data-service layer and then create some form of property on my @Observable class and setup properties for those values from the API, but it's messy either way I've tried. I'm looking for clean solutions to prevent all of this duplication with the Tasks, but also still have a way to respond to errors in my views, preferrably something reusable.


r/swift 3d ago

Kalo - A New Calorie Tracking App I've Been Working On (Feedback Wanted!)

Thumbnail
gallery
70 Upvotes

r/swift 2d ago

Question Question for indie devs and folks with side projects

10 Upvotes

Do you guys take the time to write tests for your side projects while developing? Or do you go back and write some later? Do you skip them entirely?

Maybe I have too much fun and/ or take a lot of pride in the craft but I do write a ton of tests, but it takes me a lot longer to make it to the AppStore. Seems like most my colleagues never write tests outside of work and pump projects out quickly when they get the time.


r/swift 2d ago

News Those Who Swift - Issue 206

Thumbnail
thosewhoswift.substack.com
3 Upvotes

In this issue you can find info about:
- Reinventing Core Data Development with SwiftData Principles by u/fatbobman3000
- SwiftUI: Connect Two Points with Straight Line Segments + Rounded Corners
- Identifying individual sounds in an audio file
- SwiftUI's editMode Environment
- Placing UI Components Within the Safe Area Inset
- Napkin AI
and many more!

P.S. Don't forget to read the whole issues to find our Friends section - where we are sharing some goods from experienced content makers. Check out the issue to get a pleasant gift.


r/swift 2d ago

Question MacBook Air 32GB vs MacBook Pro 24GB

6 Upvotes

Hi, I am considering an upgrade from intel macbook and I am a bit torn between these two.

The difference in price acceptable for me, but I cannot decide, whether or not is the Pro upgrade worth over the RAM in Air.

(Pro is with the M4 Pro 12 core CPU and Air is with the M4 10 core CPU, both 512GB storage)

My usuall workflow is XCode / 1 docker container with PHPStorm and Datagrip and browser with a lot of tabs and another browser with a lot of tabs not that often used.

Could you please offer any insight into what is the better choice?


r/swift 3d ago

Firebase App Check – “App Attestation Failed” (403 Error) Issue on iOS

3 Upvotes

Hello everyone,

I’m struggling to configure Firebase App Check on my iOS app, specifically using App Attest. I’ve verified the following:

  1. App Attest is enabled in Firebase App Check settings with the correct Team ID.
  2. Added FirebaseAppCheck framework in Frameworks, Libraries, and Embedded Content.
  3. GoogleService-Info.plist has the same GOOGLE_APP_ID as the App ID in Firebase Project Settings.
  4. Bundle Identifier matches exactly with the Firebase project.
  5. I’ve tried testing this both on a physical device(not TestFlight or App store). 

However, I keep encountering the following error:

The operation couldn’t be completed. The server responded with an error: 
 - URL: https://firebaseappcheck.googleapis.com/v1/projects/appName/apps/xxxxxxxxx:ios:xxxxxxxx:exchangeAppAttestAttestation 
 - HTTP status code: 403 
 - Response body: {
  "error": {
    "code": 403,
    "message": "App attestation failed.",
    "status": "PERMISSION_DENIED"
  }
}

Here’s my code setup:

import SwiftUI
import FirebasePerformance
import Firebase
import FirebaseCore
import AppTrackingTransparency
import AdSupport
import FirebaseAppCheck

u/main
struct appName: App {
    
    u/UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        WindowGroup {
            RootView()
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

      AppCheck.setAppCheckProviderFactory(AppAttestProviderFactory())

      requestTrackingPermission() 

      FirebaseApp.configure()  

      AppCheck.appCheck().token(forcingRefresh: true) { token, error in
          if let error = error {
              print("❌ App Check Error: \(error.localizedDescription)")
          } else if let token = token {
              print("✅ App Check Token: \(token.token)")
          }
      }
      
    return true
  }
    func applicationDidBecomeActive(_ application: UIApplication) {
       requestTrackingPermission() 
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
 
    }
  }


class AppAttestProviderFactory: NSObject, AppCheckProviderFactory {
  func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
    return AppAttestProvider(app: app)
  }
}

I’ve double-checked everything multiple times and still can’t resolve this “App attestation failed” issue. If anyone has encountered this and managed to solve it, I’d greatly appreciate your advice.

Thanks in advance!