{"id":3301,"url":"https://github.com/github/swift-style-guide","last_synced_at":"2025-10-04T07:31:14.684Z","repository":{"id":18579374,"uuid":"21782593","full_name":"github/swift-style-guide","owner":"github","description":"**Archived** Style guide \u0026 coding conventions for Swift projects","archived":true,"fork":false,"pushed_at":"2017-11-08T16:05:41.000Z","size":79,"stargazers_count":4774,"open_issues_count":4,"forks_count":567,"subscribers_count":261,"default_branch":"master","last_synced_at":"2024-09-30T00:05:48.937Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/github.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-13T04:05:10.000Z","updated_at":"2024-09-27T08:27:33.000Z","dependencies_parsed_at":"2022-08-07T09:00:48.644Z","dependency_job_id":null,"html_url":"https://github.com/github/swift-style-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fswift-style-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fswift-style-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fswift-style-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fswift-style-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/github","download_url":"https://codeload.github.com/github/swift-style-guide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235227462,"owners_count":18956137,"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":[],"created_at":"2024-01-05T20:16:37.539Z","updated_at":"2025-10-04T07:31:09.380Z","avatar_url":"https://github.com/github.png","language":null,"readme":"# This repository is no longer active.\n\n----\n\nA guide to our Swift style and conventions.\n\nThis is an attempt to encourage patterns that accomplish the following goals (in\nrough priority order):\n\n 1. Increased rigor, and decreased likelihood of programmer error\n 1. Increased clarity of intent\n 1. Reduced verbosity\n 1. Fewer debates about aesthetics\n\nIf you have suggestions, please see our [contribution guidelines](CONTRIBUTING.md),\nthen open a pull request. :zap:\n\n----\n\n#### Whitespace\n\n * Tabs, not spaces.\n * End files with a newline.\n * Make liberal use of vertical whitespace to divide code into logical chunks.\n * Don’t leave trailing whitespace.\n   * Not even leading indentation on blank lines.\n\n#### Prefer `let`-bindings over `var`-bindings wherever possible\n\nUse `let foo = …` over `var foo = …` wherever possible (and when in doubt). Only use `var` if you absolutely have to (i.e. you *know* that the value might change, e.g. when using the `weak` storage modifier).\n\n_Rationale:_ The intent and meaning of both keywords are clear, but *let-by-default* results in safer and clearer code.\n\nA `let`-binding guarantees and *clearly signals to the programmer* that its value will never change. Subsequent code can thus make stronger assumptions about its usage.\n\nIt becomes easier to reason about code. Had you used `var` while still making the assumption that the value never changed, you would have to manually check that.\n\nAccordingly, whenever you see a `var` identifier being used, assume that it will change and ask yourself why.\n\n#### Return and break early\n\nWhen you have to meet certain criteria to continue execution, try to exit early. So, instead of this:\n\n```swift\nif n.isNumber {\n    // Use n here\n} else {\n    return\n}\n```\n\nuse this:\n```swift\nguard n.isNumber else {\n    return\n}\n// Use n here\n```\n\nYou can also do it with `if` statement, but using `guard` is preferred, because `guard` statement without `return`, `break` or `continue` produces a compile-time error, so exit is guaranteed.\n\n#### Avoid Using Force-Unwrapping of Optionals\n\nIf you have an identifier `foo` of type `FooType?` or `FooType!`, don't force-unwrap it to get to the underlying value (`foo!`) if possible.\n\nInstead, prefer this:\n\n```swift\nif let foo = foo {\n    // Use unwrapped `foo` value in here\n} else {\n    // If appropriate, handle the case where the optional is nil\n}\n```\n\nAlternatively, you might want to use Swift's Optional Chaining in some of these cases, such as:\n\n```swift\n// Call the function if `foo` is not nil. If `foo` is nil, ignore we ever tried to make the call\nfoo?.callSomethingIfFooIsNotNil()\n```\n\n_Rationale:_ Explicit `if let`-binding of optionals results in safer code. Force unwrapping is more prone to lead to runtime crashes.\n\n#### Avoid Using Implicitly Unwrapped Optionals\n\nWhere possible, use `let foo: FooType?` instead of `let foo: FooType!` if `foo` may be nil (Note that in general, `?` can be used instead of `!`).\n\n_Rationale:_ Explicit optionals result in safer code. Implicitly unwrapped optionals have the potential of crashing at runtime.\n\n#### Prefer implicit getters on read-only properties and subscripts\n\nWhen possible, omit the `get` keyword on read-only computed properties and\nread-only subscripts.\n\nSo, write these:\n\n```swift\nvar myGreatProperty: Int {\n\treturn 4\n}\n\nsubscript(index: Int) -\u003e T {\n    return objects[index]\n}\n```\n\n… not these:\n\n```swift\nvar myGreatProperty: Int {\n\tget {\n\t\treturn 4\n\t}\n}\n\nsubscript(index: Int) -\u003e T {\n    get {\n        return objects[index]\n    }\n}\n```\n\n_Rationale:_ The intent and meaning of the first version are clear, and results in less code.\n\n#### Always specify access control explicitly for top-level definitions\n\nTop-level functions, types, and variables should always have explicit access control specifiers:\n\n```swift\npublic var whoopsGlobalState: Int\ninternal struct TheFez {}\nprivate func doTheThings(things: [Thing]) {}\n```\n\nHowever, definitions within those can leave access control implicit, where appropriate:\n\n```swift\ninternal struct TheFez {\n\tvar owner: Person = Joshaber()\n}\n```\n\n_Rationale:_ It's rarely appropriate for top-level definitions to be specifically `internal`, and being explicit ensures that careful thought goes into that decision. Within a definition, reusing the same access control specifier is just duplicative, and the default is usually reasonable.\n\n#### When specifying a type, always associate the colon with the identifier\n\nWhen specifying the type of an identifier, always put the colon immediately\nafter the identifier, followed by a space and then the type name.\n\n```swift\nclass SmallBatchSustainableFairtrade: Coffee { ... }\n\nlet timeToCoffee: NSTimeInterval = 2\n\nfunc makeCoffee(type: CoffeeType) -\u003e Coffee { ... }\n```\n\n_Rationale:_ The type specifier is saying something about the _identifier_ so\nit should be positioned with it.\n\nAlso, when specifying the type of a dictionary, always put the colon immediately\nafter the key type, followed by a space and then the value type.\n\n```swift\nlet capitals: [Country: City] = [sweden: stockholm]\n```\n\n#### Only explicitly refer to `self` when required\n\nWhen accessing properties or methods on `self`, leave the reference to `self` implicit by default:\n\n```swift\nprivate class History {\n\tvar events: [Event]\n\n\tfunc rewrite() {\n\t\tevents = []\n\t}\n}\n```\n\nOnly include the explicit keyword when required by the language—for example, in a closure, or when parameter names conflict:\n\n```swift\nextension History {\n\tinit(events: [Event]) {\n\t\tself.events = events\n\t}\n\n\tvar whenVictorious: () -\u003e () {\n\t\treturn {\n\t\t\tself.rewrite()\n\t\t}\n\t}\n}\n```\n\n_Rationale:_ This makes the capturing semantics of `self` stand out more in closures, and avoids verbosity elsewhere.\n\n#### Prefer structs over classes\n\nUnless you require functionality that can only be provided by a class (like identity or deinitializers), implement a struct instead.\n\nNote that inheritance is (by itself) usually _not_ a good reason to use classes, because polymorphism can be provided by protocols, and implementation reuse can be provided through composition.\n\nFor example, this class hierarchy:\n\n```swift\nclass Vehicle {\n    let numberOfWheels: Int\n\n    init(numberOfWheels: Int) {\n        self.numberOfWheels = numberOfWheels\n    }\n\n    func maximumTotalTirePressure(pressurePerWheel: Float) -\u003e Float {\n        return pressurePerWheel * Float(numberOfWheels)\n    }\n}\n\nclass Bicycle: Vehicle {\n    init() {\n        super.init(numberOfWheels: 2)\n    }\n}\n\nclass Car: Vehicle {\n    init() {\n        super.init(numberOfWheels: 4)\n    }\n}\n```\n\ncould be refactored into these definitions:\n\n```swift\nprotocol Vehicle {\n    var numberOfWheels: Int { get }\n}\n\nfunc maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -\u003e Float {\n    return pressurePerWheel * Float(vehicle.numberOfWheels)\n}\n\nstruct Bicycle: Vehicle {\n    let numberOfWheels = 2\n}\n\nstruct Car: Vehicle {\n    let numberOfWheels = 4\n}\n```\n\n_Rationale:_ Value types are simpler, easier to reason about, and behave as expected with the `let` keyword.\n\n#### Make classes `final` by default\n\nClasses should start as `final`, and only be changed to allow subclassing if a valid need for inheritance has been identified. Even in that case, as many definitions as possible _within_ the class should be `final` as well, following the same rules.\n\n_Rationale:_ Composition is usually preferable to inheritance, and opting _in_ to inheritance hopefully means that more thought will be put into the decision.\n\n\n#### Omit type parameters where possible\n\nMethods of parameterized types can omit type parameters on the receiving type when they’re identical to the receiver’s. For example:\n\n```swift\nstruct Composite\u003cT\u003e {\n\t…\n\tfunc compose(other: Composite\u003cT\u003e) -\u003e Composite\u003cT\u003e {\n\t\treturn Composite\u003cT\u003e(self, other)\n\t}\n}\n```\n\ncould be rendered as:\n\n```swift\nstruct Composite\u003cT\u003e {\n\t…\n\tfunc compose(other: Composite) -\u003e Composite {\n\t\treturn Composite(self, other)\n\t}\n}\n```\n\n_Rationale:_ Omitting redundant type parameters clarifies the intent, and makes it obvious by contrast when the returned type takes different type parameters.\n\n#### Use whitespace around operator definitions\n\nUse whitespace around operators when defining them. Instead of:\n\n```swift\nfunc \u003c|(lhs: Int, rhs: Int) -\u003e Int\nfunc \u003c|\u003c\u003cA\u003e(lhs: A, rhs: A) -\u003e A\n```\n\nwrite:\n\n```swift\nfunc \u003c| (lhs: Int, rhs: Int) -\u003e Int\nfunc \u003c|\u003c \u003cA\u003e(lhs: A, rhs: A) -\u003e A\n```\n\n_Rationale:_ Operators consist of punctuation characters, which can make them difficult to read when immediately followed by the punctuation for a type or value parameter list. Adding whitespace separates the two more clearly.\n\n#### Translations\n\n* [中文版](https://github.com/Artwalk/swift-style-guide/blob/master/README_CN.md)\n* [日本語版](https://github.com/jarinosuke/swift-style-guide/blob/master/README_JP.md)\n* [한국어판](https://github.com/minsOne/swift-style-guide/blob/master/README_KR.md)\n* [Versión en Español](https://github.com/antoniosejas/swift-style-guide/blob/spanish/README-ES.md)\n* [Versão em Português do Brasil](https://github.com/fernandocastor/swift-style-guide/blob/master/README-PTBR.md)\n* [فارسی](https://github.com/mohpor/swift-style-guide/blob/Persian/README-FA.md)\n","funding_links":[],"categories":["Style Guides","Programming Languages","Swift","Best Practice ##","Others","Unofficial","Codestyle","WebSocket","Guides","Objective-C","非官方"],"sub_categories":["Keychain","Swift","Version 1.x ###","Other Xcode","Other free courses","Style Guides","Vue","\u003ca name=\"other-xcode\"\u003e\u003c/a\u003e其他 Xcode 插件","Misc"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Fswift-style-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgithub%2Fswift-style-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Fswift-style-guide/lists"}