{"id":3300,"url":"https://github.com/spotify/ios-style","last_synced_at":"2025-05-11T16:12:01.152Z","repository":{"id":26778843,"uuid":"30237002","full_name":"spotify/ios-style","owner":"spotify","description":"Guidelines for iOS development in use at Spotify","archived":false,"fork":false,"pushed_at":"2020-08-10T14:43:19.000Z","size":16,"stargazers_count":244,"open_issues_count":0,"forks_count":36,"subscribers_count":130,"default_branch":"master","last_synced_at":"2025-05-11T10:08:59.959Z","etag":null,"topics":["code-style","coding-style","objective-c","spotify","style-guide"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spotify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-03T10:15:41.000Z","updated_at":"2025-05-09T08:02:33.000Z","dependencies_parsed_at":"2022-08-31T23:40:35.459Z","dependency_job_id":null,"html_url":"https://github.com/spotify/ios-style","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/spotify%2Fios-style","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fios-style/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fios-style/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fios-style/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spotify","download_url":"https://codeload.github.com/spotify/ios-style/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253551260,"owners_count":21926257,"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":["code-style","coding-style","objective-c","spotify","style-guide"],"created_at":"2024-01-05T20:16:37.499Z","updated_at":"2025-05-11T16:12:01.126Z","avatar_url":"https://github.com/spotify.png","language":null,"funding_links":[],"categories":["Style Guides","Objective-C","Unofficial","WebSocket","非官方"],"sub_categories":["Keychain","Vue","Other Xcode","Other free courses","\u003ca name=\"other-xcode\"\u003e\u003c/a\u003e其他 Xcode 插件","Misc"],"readme":"Spotify Objective-C Coding Style\n================================\n\nVersion: 0.9.0\n\nOur general coding conventions at Spotify are documented on an internal wiki, but specifics for Objective-C and\nObjective-C++ code in the iOS client are documented here.\n\nLicense\n-------\nCopyright (c) 2015-2016 Spotify AB. \n\nThis work is licensed under a [Creative Commons Attribution 4.0 International License]( http://creativecommons.org/licenses/by/4.0/).\n\nTable of Contents\n-----------------\n\n1.  [Spacing, Lines and Formatting](#spacing-lines-and-formatting)\n2.  [Brackets](#brackets)\n3.  [Naming](#naming)\n4.  [Comments](#comments)\n5.  [Pragma Marks](#pragma-marks)\n6.  [Constants](#constants)\n7.  [Return Early](#return-early)\n8.  [Initializers](#initializers)\n9.  [Headers](#headers)\n10. [Nullability](#nullability)\n11. [Strings](#strings)\n12. [Dot Notation](#dot-notation)\n13. [Categories](#categories)\n\nSpacing, Lines and Formatting\n-----------------------------\n\n### Line length\n* Keep your lines within **120** characters width when possible.\n  * In Xcode, you can set a page guide in Text Editing in Preferences.\n\n### Whitespace\n* Use **4** spaces for indentation and alignment. Do not use tabs.\n* Trailing whitespace is acceptable only on blank lines, but discouraged even there.\n  * In Xcode, select \"Automatically trim whitespace\" and \"Including whitespace-only lines\" in Text Editing preferences\n    to handle this automatically.\n* Put spaces after commas, and before and after operators.\n* Do not put spaces between parentheses and what they are enclosing.\n\n**Example:**\n```objc\nfoo(\"bar\") \n```\n\n**Not:**\n\n```objc\nfoo( \"bar\" )\n```\n\n### Containers\n* Array one-liners are acceptable unless they have too many items or their values are too long.\n\n```objc\nNSArray *array = @[@\"uno\", @\"dos\", @\"tres\", @\"cuatro\"];\n```\n\n* In that case, break them in several lines:\n\n```objc\nNSArray *array = @[\n    @\"This is how we do, yeah, chilling, laid back\",\n    @\"Straight stuntin’ yeah we do it like that\",\n    @\"This is how we do, do do do do, this is how we do\",\n];\n```\n\n* Dictionary one-liners are reserved for single pairs only:\n\n```objc\nNSDictionary *dict = @{@\"key\" : @\"highway\"};\n```\n\n* Format it pretty otherwise, leaving a trailing comma after the last item:\n```objc\nNSDictionary *dict = @{\n    @\"key1\" : @\"highway\",\n    @\"key2\" : @\"heart\",\n};\n```\n\nBrackets\n--------\n* Always use brackets for `if` / `for` / `while` / `do`-`while` statements. Even if its a one-liner:\n\n```objc\nif (itsMagic) {\n    [self makeItEverlasting];\n}\n```\n\n* Write follow up `else` clauses after the previous closing bracket on the same line.\n\n```objc\nif (hasClue) {\n    knowExactlyWhatToDo();\n} else if (seeItAllSoClear) {\n    writeItDown();\n} else {\n    sing();\n    dance();\n}\n```\n\nNaming\n------\n* Follow Apple’s [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)\non naming.\n\nComments\n--------\n* Use the `//` style for single line comments or when appending comments in the same line of code.\n* Use the `/* */` style for multi-line comments.\n\n**Example:**\n```objc\n/*\n This is a multi-line comment. The opening and closing markers are on their\n own lines.\n\n This is a new paragraph in the same block comment.\n */\n\nstop(); // Hammer-time!\n\n// this is a very brief comment.\n```\n\n* Document all methods and properties in the headers using Xcode’s documentation style (which is `///` at the time of writing). \nYou can select a property or method and use `Option`+`Cmd`+`/` to generate the documentation template for it. Make sure to use the available \nmarkup tags like `@param`, `@return`, etc. (these will be auto-generated for you by Xcode).\n\nPragma Marks\n------------\n* Use the pre-processor instruction `#pragma mark` to mark related groups of methods.\n\nConstants\n---------\n* Do not define constants using `#define`.\n* Publicly (or privately) exposed variables should be constant (trying to assign values will result in compilation\nerror).\n\n```objc\nextern NSString * const SPTCodeStandardErrorDomain;\n```\n\nReturn Early\n------------\n* Return early on errors and failed pre-conditions to avoid unnecessary nested brackets and / or unnecessary\ncomputations.\n\n**Example:**\n\n```objc\n- (void)setFireToTheRain:(id)rain\n{\n    if ([_rain isEqualTo:rain]) {\n        return;\n    }\n\n    _rain = rain;\n}\n```\n\nInitializers\n------------\n* Follow [Apple's typical init format](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW11) to initialize objects.\n\n**Example:**\n\n```objc\n- (instancetype)init \n{\n    self = [super init];\n \n    if (self) {\n        // initialize instance variables here\n    }\n \n    return self;\n}\n```\n\nHeaders\n-------\n* The use of prefix headers has been deprecated. Do not add new code to an existing prefix header.\n* When importing a module use the hash-import variant instead of at-import.\n  * Yes: `#import \u003cFoundation/Foundation.h\u003e`\n  * No: `@import Foundation;`\n\nNullability\n-----------\n* Use `NS_ASSUME_NONNULL_BEGIN` and `NS_ASSUME_NONNULL_END` in header files, and explicitly add `nullable` when needed. Example:\n```objc\n#import \u003cFoundation/Foundation.h\u003e\n\n@protocol SPTPlaylist;\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef void(^SPTSomeBlock)(NSData * _Nullable data, NSError * _Nullable error);\n\n@interface SPTYourClass : NSObject\n\n@property (nonatomic, copy, readonly, nullable) NSString *customTitle;\n@property (nonatomic, strong, readonly) id\u003cSPTPlaylist\u003e playlist;\n\n- (nullable instancetype)initWithPlaylist:(id\u003cSPTPlaylist\u003e)playlist\n                              customTitle:(nullable NSString *)customTitle;\n\n@end\n\nNS_ASSUME_NONNULL_END\n```\n\nStrings\n-------\n* All strings presented to the user should be localized.\n\nDot Notation\n------------\n* Use bracket notation when calling non-accessor methods:\n\n```objc\n[self doSomething];\n```\n\n* Use bracket notation when accessing globals through a class method:\n\n```objc\n[MyClass sharedInstance];\n```\n\n* Set and access properties using dot notation:\n\n```objc\nself.myString = @\"A string\";\n```\n\n* Except in the `init` or `dealloc` methods, always use the ivar directly there:\n\n```objc\n_myString = nil;\n```\n\nCategories\n----------\n* Methods in categories on non-Spotify classes must be prefixed `spt_` to avoid name clashes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspotify%2Fios-style","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspotify%2Fios-style","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspotify%2Fios-style/lists"}