{"id":13995486,"url":"https://github.com/uber/cyborg","last_synced_at":"2025-06-11T17:40:12.108Z","repository":{"id":58694428,"uuid":"143788110","full_name":"uber/cyborg","owner":"uber","description":"Display Android Vectordrawables on iOS.","archived":false,"fork":false,"pushed_at":"2020-09-30T18:43:01.000Z","size":380,"stargazers_count":302,"open_issues_count":15,"forks_count":19,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-11-29T18:40:20.094Z","etag":null,"topics":["incubation"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-06T22:03:38.000Z","updated_at":"2024-09-29T18:39:24.000Z","dependencies_parsed_at":"2022-09-06T12:23:08.358Z","dependency_job_id":null,"html_url":"https://github.com/uber/cyborg","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/uber/cyborg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fcyborg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fcyborg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fcyborg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fcyborg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uber","download_url":"https://codeload.github.com/uber/cyborg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fcyborg/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259308162,"owners_count":22837974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["incubation"],"created_at":"2024-08-09T14:03:26.461Z","updated_at":"2025-06-11T17:40:12.074Z","avatar_url":"https://github.com/uber.png","language":"Swift","readme":"# Cyborg\n\n[![Build Status](https://travis-ci.com/uber/cyborg.svg?branch=master)](https://travis-ci.com/uber/cyborg)\n[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2961/badge)](https://bestpractices.coreinfrastructure.org/projects/2961)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\n\nCyborg is a [partial](https://github.com/uber/cyborg/issues?q=is%3Aissue+is%3Aopen+label%3A%22Spec+Compliance%22) port of Android's [VectorDrawable](https://medium.com/androiddevelopers/understanding-androids-vector-image-format-vectordrawable-ab09e41d5c68) to iOS.\nIt is intended as a replacement for UIImages, Icon Fonts, and Apple's PDF vector image option. The VectorDrawable format provides a number of advantages:\n\n- Full theming support of individual elements of an illustration, beyond simple image tinting or changing the text color in an Icon Font\n- Ability to use one asset for both platforms, simplifying the design -\u003e engineering pipeline\n- Assets are resolution independent\n- RTL support\n- Easily convertible from SVG using Android Studio or third-party tools\n\nCyborg also supports MacOS (AppKit), TvOS, and can be used from SwiftUI. However, be aware that these implementations are currently less mature than the iOS version.\n\n## Performance Comparisons\n\nWe benchmarked Cyborg against a number of alternatives, loading the 50+ icons contained in our Driver app's icon set.\n\n- Cyborg's parser is faster than the iOS SVG libraries we could find\n- It tends to be a tiny bit slower than `UIImage`. The differences should be in the fractions of milliseconds in practice\n- An icon font with ~50 icons can be loaded in the time that it takes to load around 2-3 drawables of similar complexity.\n\nIf parsing performance becomes an issue, you may wish to implement either a caching mechanism appropriate for your application, or take advantage of Cyborg's thread safety to perform parsing off the main thread.\n\nWith that said, many performance improvement opportunities [currently](https://github.com/uber/cyborg/issues?q=is%3Aissue+is%3Aopen+label%3APerformance) exist, so performance should improve in the future.\nAs of this writing, Swift is a young language, and performance improvements to it, particularly in String creation, closures, and ownership should also have a positive impact on Cyborg's performance.\n\nThe full list of features is enumerated in the [Android Documentation](https://developer.android.com/reference/android/graphics/drawable/VectorDrawable).\n\n## Installing Cyborg\n\nCyborg supports Swift Package Manager and Carthage. \n\nTo install using Carthage: \n\n1. Get [Carthage](https://github.com/Carthage/Carthage#quick-start).\n2. Add the following to your CartFile: `github \"uber/cyborg\" ~\u003e [desired version]`\n\nTo add Cyborg to an Xcode project using Swift Package Manager, follow the [instructions provided by Apple](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app). \n\n## Using Cyborg\n\nAfter following the integration steps below, using Cyborg requires only slightly more code than using a `UIImage`:\n\n```swift\nlet vectorView = VectorView(theme: myTheme)\nvectorView.drawable = VectorDrawable.named(\"MyDrawable\")\n```\n\n## Integration\n\nCyborg is made to scale up to complex uses cases, and as such require a bit of configuration to get the clean code sample above.\n\nLet's see how to write the minimal integration to get started:\n\n### Implementing Themes and Resources\n\nOne of the best features of VectorDrawables is the ability to swap in arbitrary values at runtime. Well authored VectorDrawable assets can change their colors in response to changes in app state, such as a night mode.\n\nHowever, gaining access to these powerful features requires us to write our own Theme and Resource providers:\n\n```swift\nclass Theme: Cyborg.ThemeProviding {\n\n    func colorFromTheme(named _: String) -\u003e UIColor {\n        return .black\n    }\n\n}\n\nclass Resources: ResourceProviding {\n\n    func colorFromResources(named _: String) -\u003e UIColor {\n        return .black\n    }\n\n}\n\n```\n\nAssuming that resources never change, we can now write the convenience initializer depicted in the first code sample:\n\n```swift\nfileprivate let resources = Resources()\n\nextension VectorDrawable {\n    public convenience init(theme: Theme) {\n        self.init(theme: theme, resources: resources()\n    }\n}\n\n```\n\n### Reporting Drawable Parse Errors:\n\nIf, for some reason, you provide an invalid VectorDrawable to Cyborg, the standard creation function in Cyborg will give you a detailed error message that you can report\nas a nonfatal to the crash reporting service of your choice and use to debug locally. This can be handled at your app's \"platform\" level, allowing you to write code that assumes that\nthe parsing always succeeds, just like with UIImage:\n\n```swift\nextension VectorDrawable {\n    public static func named(_ name: String) -\u003e VectorDrawable? {\n        return Bundle.main.url(forResource: name, withExtension: \"xml\").flatMap { url in\n        switch VectorDrawable.create(from: url) {\n            case .ok(let drawable):\n                return drawable\n            case .error(let error):\n               myAssertionFailureThatAlsoReportsToBackend(\"Could not create a vectordrawable named \\(name); the error was \\(error)\")\n               return nil\n        }\n    }\n}\n```\n\n## Best Practices\n\n### Lint VectorDrawable Assets\n\nAs you may already have noticed, the Theme and Resource objects you wrote in an earlier section are [stringly typed](http://wiki.c2.com/?StringlyTyped). To prevent issues with assets that reference nonexistent theme or resource colors,\nyou may want to lint the xml files to ensure that they are valid.\n\n### Store Your VectorDrawables in a Single Repo\n\nYou may find it convenient to allow designers to commit new assets directly to a repo that can be pulled into your Android and iOS repos by designers.\n\n### Snapshot Test Your VectorDrawables\n\nThe easiest way to ensure correctness of your UIs that use static vector drawables is to snapshot test the UIs that use them using a tool like [iOSSnapshotTestCase](https://github.com/uber/ios-snapshot-test-case).\nThis will ensure that any code that isn't compiler-verified matches your expectations.\n","funding_links":[],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuber%2Fcyborg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuber%2Fcyborg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuber%2Fcyborg/lists"}