GithubHelp home page GithubHelp logo

lukepistrol / sfsymbolsmacro Goto Github PK

View Code? Open in Web Editor NEW
175.0 3.0 2.0 46 KB

A Swift Macro for "type-safe" SF Symbols.

License: MIT License

Swift 100.00%
swift swift-macros swift-package swift-package-manager swiftui xcode15 swift5-9

sfsymbolsmacro's Introduction

GitHub Twitter: @lukeeep_

SFSymbolsMacro

This Swift Macro provides an easy way to make the use of SF Symbols in Swift more or less "type-safe".

Installation

Xcode

  1. Click File > Add Package Dependencies
  2. Paste the following link into the search field on the upper-right:
    https://github.com/lukepistrol/SFSymbolsMacro.git
    

Swift Package Manager

In Package.swift:

dependencies: [
    .package(url: "https://github.com/lukepistrol/SFSymbolsMacro.git", from: "0.1.0")
]

And then add the dependency to your targets.

Usage

Simply create an enum which will hold all the SF Symbols for your project:

enum Symbols: String {
    case circle
    case circleFill = "circle.fill"
    case shareIcon = "square.and.arrow.up"
    case globe
}

Then simply import SFSymbolsMacro and add the @SFSymbol macro annotation to the enum:

import SFSymbolsMacro
import SwiftUI

@SFSymbol
enum Symbols: String { ... }

The macro will then validate each case and the expanded macro will look something like this:

enum Symbols: String {
    case circle
    case circleFill = "circle.fill"
    case shareIcon = "square.and.arrow.up"
    case globe

    var image: Image {
        Image(systemName: self.rawValue)
    }
    var name: String {
        self.rawValue
    }
    #if canImport(UIKit)
    func uiImage(configuration: UIImage.Configuration? = nil) -> UIImage {
        UIImage(systemName: self.rawValue, withConfiguration: configuration)!
    }
    #else
    func nsImage(accessibilityDescription: String? = nil) -> NSImage {
        return NSImage(systemSymbolName: self.rawValue, accessibilityDescription: accessibilityDescription)!
    }
    #endif
    func callAsFunction() -> String {
        return self.rawValue
    }
}

In your code you can then call a symbol:

var body: some View {
    VStack {
        Symbols.circleFill.image
        Label("Globe", systemImage: Symbols.globe.name)
        // the above can also be written as
        Label("Globe", systemImage: Symbols.globe())
    }
}

In case the provided raw value is not a valid SF Symbol, Xcode will show a compile error at the enum-case in question:

explicit raw value

inferred raw value

Contribution

If you have any ideas on how to take this further I'm happy to discuss things in an issue.


Buy Me A Coffee

sfsymbolsmacro's People

Contributors

hi2gage avatar lukepistrol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

sfsymbolsmacro's Issues

'image' not found when using this macro within #Preview macro

Not sure if this is a limitation of swift macros, or a bug in this library, but I thought I'd leave this here.

Seems the SFSymbol macro does not work within swiftui #Previews

Sample code:

import SFSymbolsMacro
import SwiftUI

@SFSymbol
enum Symbol: String {
    case archive = "archivebox"
    case arrowUpRightSquare = "arrow.up.right.square"
    case chevronForward = "chevron.forward"
    case checkmark = "checkmark"
    case checkmarkCircleFill = "checkmark.circle.fill"
    case checkmarkShieldFill = "checkmark.shield.fill"
    case clockArrowCirclepath = "clock.arrow.circlepath"
    case dismissKeyboard = "keyboard.chevron.compact.down"
    case ellipsis
    case exclamationmarkCircleFill = "exclamationmark.circle.fill"
    case message = "message"
    case personCircleFill = "person.circle.fill"
    case phone = "phone"
    case questionMarkCircleFill = "questionmark.circle.fill"
    case trash
    case xmarkCircleFill = "xmark.circle.fill"
}

Does not work:

#Preview {
    Label {
        Text("Some Text")
    } icon: {
        Symbol.checkmarkShieldFill.image // Value of type 'Symbol' has no member 'image'
    }
}

Works:

let icon =  Symbol.checkmarkShieldFill.image
#Preview {
    Label {
        Text("Some Text")
    } icon: {
        icon
    }
}

Some SF Symbols cases will raise errors.

Description: I imported this repository as an SPM to my project, and here's my code:

import SFSymbolsMacro

@SFSymbol
enum Symbols: String {
    case figureChildAndLockFill = "figure.child.and.lock.fill"     // This symbol encounters an error: "figure.child.and.lock.fill" is not a valid SF Symbol.
    ... // other valid cases
}

And I can confirm that the 'invalid symbol' is in SF Symbols beta 5 for sure. The snapshot below shows it:

CleanShot 2023-09-20 at 18 03 28@2x

So, why can some symbol names satisfy the compiler while others cannot?

Environment:
Xcode Version 15.0 (15A240d)
SF Symbols Beta 5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.