├── MFR_quickhelp_eg_2x.png ├── MFR_symbol_markup_eg_2x.png ├── Organise Xcode files.md ├── Organize files in Xcode by functionality.md ├── ProjectFolder.png ├── README.md └── organize-by-functionality.jpeg /MFR_quickhelp_eg_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anas-p/iOS-Best-Practices-Coding-Style/e674e13e8c2111b209bb9c9f62c81b24d7b27a3a/MFR_quickhelp_eg_2x.png -------------------------------------------------------------------------------- /MFR_symbol_markup_eg_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anas-p/iOS-Best-Practices-Coding-Style/e674e13e8c2111b209bb9c9f62c81b24d7b27a3a/MFR_symbol_markup_eg_2x.png -------------------------------------------------------------------------------- /Organise Xcode files.md: -------------------------------------------------------------------------------- 1 | # Organize files in Xcode by Group 2 | - **Data Manager/** 3 | - Data/ 4 | - DataStack1 5 | - DataStack2 6 | - etc 7 | - Network/ 8 | - NetworkRouter 9 | - etc 10 | - Util/ 11 | - foundation extensions, helper classes 12 | 13 | - **Library/** 14 | - External library 1 15 | - External library 2 16 | 17 | - **Storyboards/** 18 | - Tab1.storyboard 19 | - Tab2.storyboard 20 | 21 | - **UI/** 22 | - Tab1 (or Functionality Area 1)/ 23 | - ViewController1 24 | - ViewController2 25 | - Views/ 26 | - Tab2 (or Functionality Area 2)/ 27 | - ViewController1 28 | - ViewController2 29 | - Views/ 30 | - Common/ 31 | - SharedUIComponent1 32 | - SharedUIComponent2 33 | 34 | - **Utilities/** 35 | - Extensions of Cocoa classes 36 | - Colors helper 37 | - Fonts helper 38 | - etc 39 | 40 | - **Resources/** 41 | - Fonts/ 42 | - Placeholder images (final images go into .XCAssets file) 43 | - etc 44 | 45 | 46 | ### Data Manager 47 | - separate directories for each kind of data being managed (usually a DataManager singleton and a collection of object classes). 48 | - A directory for all the networking code. 49 | - A directory for any extensions or other backend/data helper classes. 50 | - API Request classes 51 | - Core data classes 52 | 53 | ### Storyboards 54 | - Simple flat directory for the collection of storyboards. Makes them easy to find. 55 | 56 | ### Library 57 | - Each external library gets a folder here. A lot of the time it's easier to include this way (especially if it requires changes) than doing a link with CocoaPods or Carthage. 58 | 59 | ### UI 60 | - Each area of the app gets its own folder. This might be by tab, or by other high level UI "concept." Within the folder there are the appropriate view controllers, and a sub folder for all the custom views. If there are a LOT of views the Views folder might be further broken down 61 | 62 | - There's also a Common folder. Any UI component that gets used across more than one UI folder gets promoted to Common. Common gets further organized when it gets big. 63 | 64 | - The UI/Util folder is for things like a Color manager, Fonts manager, and extensions to the Cocoa classes. 65 | 66 | ### Resources 67 | - This is where fonts live. It might also hold things like string tables for localization, and placeholder images during development (final images are all in XCAssets, but that file can get burly, so it's nice to have placeholder stuff here so you know to delete it) 68 | 69 | -------------------------------------------------------------------------------- /Organize files in Xcode by functionality.md: -------------------------------------------------------------------------------- 1 | # Organize files in Xcode by Functionality 2 | Sample Screenshot: 3 | 4 | ![Project Files Sample](https://github.com/anasamanp/iOS-Best-Practices-Coding-Style/blob/master/ProjectFolder.png) 5 | 6 | - **Constants.swift** or **Enums.swift**, which contains `enum`s for all static constants used in the app like *Urls*, *UserDefault keys*, *Alert Messages*. 7 | - **Structs.swift**, which contains common `struct`s used in the app. 8 | - **AppDelegate.swift**, the starting point for your app, logically placed at the top of the folder structure. 9 | - **API**, the API folder contains a subfolder for *APIRequest* and *Models* because they’re closely related to the APIs themselves. 10 | - Then almost all the other folders are specific UIs. Every **UI** has its own **Swift class** file and a **XIB**. Any UI that’s part of another UI, such as the ***“Search Popover Controller”*** which is part of the ***"Appointment View Controller"***, is structured as a subfolder. 11 | - In the **Supporting Files** you can see a few subdirectories, for extensions for instance, 12 | - Organize classes and **XIB**s by functionality, nested by sub-functionality or sub-UI. 13 | - Non-UI, framework-like code has its own folders, like **API**. 14 | Models have their own folders. 15 | - Generic UI code, like subclassing **UINavigationController**, goes lower down on the UI-folder list. 16 | - Support files, like **extensions**, **utilities** and **non-source-controlled libraries** go in their own folder. 17 | -------------------------------------------------------------------------------- /ProjectFolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anas-p/iOS-Best-Practices-Coding-Style/e674e13e8c2111b209bb9c9f62c81b24d7b27a3a/ProjectFolder.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Swift Coding Style guide 2 | 3 | ## Organize files in Xcode: 4 | - **[by Functionality](https://github.com/anasamanp/iOS-Best-Practices-Coding-Style/blob/master/Organize%20files%20in%20Xcode%20by%20functionality.md)** - Recommended 5 | - **[by Group](https://github.com/anasamanp/iOS-Best-Practices-Coding-Style/blob/master/Organise%20Xcode%20files.md)** 6 | 7 | ## Fundamentals: 8 | - **Clarity at the point of use** is most important goal. Entities such as **methods** and **properties** are declared only once but used repeatedly. 9 | - **Write a documentation comment** for every declaration. Insights gained by writing documentation can have a profound impact on your design, so don’t put it off. 10 | - Use Swift’s [dialect of Markdown](https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/) for documentation. 11 | - [Reference for inline documentation](http://nshipster.com/swift-documentation/). 12 | - **Begin with a summary** that describes the entity being declared. Often, an API can be completely understood from its declaration and its summary. 13 | 14 | ```swift 15 | /// Returns a 'view' of 'self' containing the same elements in 16 | /// reverse order. 17 | func reversed() -> ReverseCollection 18 | ``` 19 | - **Focus on the summary**; it’s the most important part. Many excellent documentation comments consist of nothing more than a great summary. 20 | - **Use a single sentence fragment** if possible, ending with a period. Do not use a complete sentence. 21 | - **Describe what a function or method does and what it returns**, omitting null effects and Void returns. 22 | 23 | ## Naming: 24 | **Promote Clear Usage** 25 | - **Include all the words needed to avoid ambiguity** for a person reading code where the name is used. 26 | - **Name variables, parameters, and associated types according to their roles**, rather than their type constraints. 27 | - **Make the name descriptive**. 28 | 29 | **Incorrect** 30 | ```swift 31 | var string = "Hello" 32 | var textField1 = UITextField() 33 | @IBOutlet weak var label: UILabel! 34 | @IBOutlet weak var image: UIImageView! 35 | ``` 36 | **Correct** 37 | ```swift 38 | var greeting = "Hello" 39 | var txtName = UITextField() 40 | @IBOutlet weak var lblAge: UILabel! 41 | @IBOutlet weak var imgProfile: UIImageView! 42 | ``` 43 | ## Conventions: 44 | - **Follow case conventions**. Names of types and protocols are `UpperCamelCase`. Everything else is `lowerCamelCase`. 45 | 46 | ```swift 47 | var utf8Bytes: [UTF8.CodeUnit] 48 | var isRepresentableAsASCII = true 49 | var userSMTPServer: SecureSMTPServer 50 | ``` 51 | ```swift 52 | var radarDetector: RadarScanner 53 | var enjoysScubaDiving = true 54 | ``` 55 | ## Parameters: 56 | > func move(from **start**: Point, to **end**: Point) 57 | 58 | - **Write documention for each Parameter, Throws, and Returns**. 59 | 60 | ```swift 61 | /** 62 | Repeats a string `times` times. 63 | 64 | - Parameter str: The string to repeat. 65 | - Parameter times: The number of times to repeat `str`. 66 | 67 | - Throws: `MyError.InvalidTimes` if the `times` parameter 68 | is less than zero. 69 | 70 | - Returns: A new string with `str` repeated `times` times. 71 | */ 72 | func repeatString(str: String, times: Int) throws -> String { 73 | guard times >= 0 else { throw MyError.InvalidTimes } 74 | return Repeat(count: 5, repeatedValue: "Hello").joinWithSeparator("") 75 | } 76 | ``` 77 | 78 | ## Structure of a Class file: 79 | Using `MARK:` comment is a great way to group your methods, especially in view controllers. 80 | 81 | ```swift 82 | 83 | import SomeExternalFramework 84 | 85 | //MARK: Protocols declarations 86 | //Protocol name should be end purpose of protocol 87 | //ex: FooDelegate , FooDataSource 88 | protocol ProtocolNameDelegate { 89 | func foo(param1: String, param2: Bool) 90 | } 91 | 92 | /** 93 | Documentation for the class/file 94 | */ 95 | 96 | class MyViewcontroller : UIViewController{ 97 | 98 | //MARK: Delegate initialization 99 | var delegate: ProtocolNameDelegate? 100 | 101 | //MARK: Outlets 102 | @IBOutlet weak var tableView: UITableView! 103 | @IBOutlet weak var btnSubmit: UIButton! 104 | 105 | // Custom initializers go here 106 | private let fooStringConstant = "FooConstant" 107 | private let floatConstant = 1234.5 108 | 109 | // MARK: View Lifecycle 110 | override func viewDidLoad() { 111 | super.viewDidLoad() 112 | // ... 113 | } 114 | 115 | override func viewDidLayoutSubviews() { 116 | super.viewDidLayoutSubviews() 117 | // ... 118 | } 119 | 120 | // MARK: User Interaction - Actions & Targets 121 | 122 | //Add OnClick as prefix along with same outlet name for button actions 123 | @IBAction func btnSubmitOnClick(_ sender: UIButton) { 124 | // ... 125 | } 126 | 127 | func foobarButtonTapped() { 128 | // ... 129 | } 130 | 131 | // MARK: Additional Helpers 132 | private func displayNameForFoo(foo: Foo) { 133 | // ... 134 | } 135 | } 136 | 137 | // MARK: - UITableViewDataSource 138 | extension MyViewcontroller: UITableViewDataSource { 139 | // Table view data source methods 140 | } 141 | 142 | // MARK: - UIScrollViewDelegate 143 | extension MyViewcontroller: UIScrollViewDelegate { 144 | // Scroll view delegate methods 145 | } 146 | 147 | //MARK: Extension - Name of extension class 148 | /** 149 | - Documentation for purpose of extension 150 | */ 151 | extension SomeOtherClass: UIViewController { 152 | func foobar(foobar: Foobar, somethingWithFoo foo: Foo) { 153 | // ... 154 | } 155 | } 156 | ``` 157 | 158 | **Sample markup description for documentation:** 159 | 160 | Markup for Swift 161 | 162 | ![Markup for Swift symbols](https://github.com/anasamanp/iOS-Best-Practices-Coding-Style/blob/master/MFR_symbol_markup_eg_2x.png) 163 | 164 | The Quick Help shown the above markup description 165 | 166 | ![Custom Quick Help](https://github.com/anasamanp/iOS-Best-Practices-Coding-Style/blob/master/MFR_quickhelp_eg_2x.png) 167 | 168 | # Must Follow: 169 | ## 1. Native Swift Types 170 | - Use Swift types whenever possible (Array, Dictionary, Set, String, etc.) as opposed to the NS* types from Objective-C 171 | 172 | **Incorrect** 173 | ```swift 174 | let pageLabelText = NSString(format: "%@/%@", currentPage, pageCount) 175 | 176 | //Do not make NSArray, NSDictionary, and NSSet properties or variables 177 | var arrayOfJSONObjects: NSArray = NSArray() 178 | ... 179 | let names: AnyObject? = arrayOfJSONObjects.value(forKeyPath: "name") 180 | ``` 181 | **Correct** 182 | ```swift 183 | let pageLabelText = "\(currentPage)/\(pageCount)" 184 | let alsoPageLabelText = currentPage + "/" + pageCount 185 | 186 | //cast Swift type in order to use objectice-C method. 187 | var arrayOfJSONObjects = [[String: AnyObject]]() 188 | ... 189 | let names: AnyObject? = (arrayOfJSONObjects as NSArray).value(forKeyPath: "name") 190 | ``` 191 | 192 | ## 2. Avoid force unwrapping optionals 193 | - Avoid force unwrapping optionals by using `!` or `as!` as this will cause app to crash if the value trying to use is `nil`. Safely unwrap the optional first by using things like `guard let`, `if let`, `guard let as?`, `if let as?`, and optional chaining. 194 | 195 | ## 3. Error Handling: 196 | - **Forced-try Expression** 197 | - **Avoid using the forced-try expression**: `try!` 198 | **Incorrect** 199 | ```swift 200 | // This will crash at runtime if there is an error parsing the JSON data! 201 | let json = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) 202 | print(json) 203 | ``` 204 | **Correct** 205 | ```swift 206 | do { 207 | let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) 208 | print(json) 209 | } catch { 210 | print(error) 211 | } 212 | ``` 213 | - **Let vs. Var** 214 | - Whenever possible use let instead of var. 215 | - Declare properties of an **object** or **struct** that shouldn't change over its lifetime with `let`. 216 | 217 | - **Access Control** 218 | - Prefer `private` properties and methods whenever possible to encapsulate and limit access to internal object state. 219 | - For `private` declarations at the top level of a file that are outside of a type, explicitly specify the declaration as `fileprivate`. This is functionally the same as marking these declarations private, but clarifies the scope: 220 | 221 | **Incorrect** 222 | ```swift 223 | import Foundation 224 | 225 | // Top level declaration 226 | private let foo = "bar" 227 | 228 | struct Baz { 229 | ... 230 | ``` 231 | **Correct** 232 | ```swift 233 | import Foundation 234 | 235 | // Top level declaration 236 | fileprivate let foo = "bar" 237 | 238 | struct Baz { 239 | ... 240 | ``` 241 | - If you need to expose functionality to other modules, prefer `public` classes and class members whenever possible to ensure functionality is not accidentally overridden. Better to expose the class to `open` for subclassing when needed. 242 | 243 | ## 4. Spacing 244 | - Open curly braces on the same line as the statement and close on a new line. 245 | - Put `else` statements on the same line as the closing brace of the previous `if` block. 246 | - Make all colons left-hugging (no space before but a space after) except when used with the ternary operator (a space both before and after). 247 | 248 | **Incorrect** 249 | ```swift 250 | class SomeClass : SomeSuperClass 251 | { 252 | private let someString:String 253 | 254 | func someFunction(someParam :Int) 255 | { 256 | let dictionaryLiteral : [String : AnyObject] = ["foo" : "bar"] 257 | 258 | let ternary = (someParam > 10) ? "foo": "bar" 259 | 260 | if someParam > 10 { ... } 261 | 262 | else { 263 | ... 264 | } } } 265 | ``` 266 | **Correct** 267 | ```swift 268 | class SomeClass: SomeSuperClass { 269 | private let someString: String 270 | func someFunction(someParam: Int) { 271 | let dictionaryLiteral: [String: AnyObject] = ["foo": "bar"] 272 | 273 | let ternary = (someParam > 10) ? "foo" : "bar" 274 | 275 | if someParam > 10 { 276 | ... 277 | } else { 278 | ... 279 | } 280 | } 281 | } 282 | ``` 283 | ## 5. Protocols 284 | - **Protocol Conformance** 285 | - When adding protocol conformance to a type, use a separate extension for the protocol methods. This keeps the related methods grouped together with the protocol and can simplify instructions to add a protocol to a type with its associated methods. 286 | - Use a `// MARK: - SomeDelegate` comment to keep things well organized. 287 | 288 | **Incorrect** 289 | ```swift 290 | class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate { 291 | // All methods 292 | } 293 | ``` 294 | **Correct** 295 | ```swift 296 | class MyViewcontroller: UIViewController { 297 | ... 298 | } 299 | 300 | // MARK: - UITableViewDataSource 301 | extension MyViewcontroller: UITableViewDataSource { 302 | // Table view data source methods 303 | } 304 | 305 | // MARK: - UIScrollViewDelegate 306 | extension MyViewcontroller: UIScrollViewDelegate { 307 | // Scroll view delegate methods 308 | } 309 | ``` 310 | 311 | - **Delegate Protocols** 312 | - If your protocol should have **optional methods**, it must be declared with the `@objc` attribute. 313 | - Declare protocol definitions near the class that uses the delegate, not the class that implements the delegate methods. 314 | - If more than one class uses the same protocol, declare it in its own file. 315 | - Use `weak` optional `var`s for delegate variables to avoid retain cycles. 316 | 317 | ```swift 318 | //SomeTableCell.swift 319 | protocol SomeTableCellDelegate: class { 320 | func cellButtonWasTapped(cell: SomeTableCell) 321 | } 322 | 323 | class SomeTableCell: UITableViewCell { 324 | weak var delegate: SomeTableCellDelegate? 325 | // ... 326 | } 327 | ``` 328 | ```swift 329 | //SomeTableViewController.swift 330 | class SomeTableViewController: UITableViewController { 331 | // ... 332 | } 333 | 334 | // MARK: - SomeTableCellDelegate 335 | extension SomeTableViewController: SomeTableCellDelegate { 336 | func cellButtonWasTapped(cell: SomeTableCell) { 337 | // Implementation of cellbuttonwasTapped method 338 | } 339 | } 340 | ``` 341 | ## 6. Arrays and Dictionaries 342 | - **Type Shorthand Syntax** 343 | Use square bracket shorthand type syntax for Array and Dictionary as recommended by Apple in [Array Type Shorthand Syntax](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html#//apple_ref/doc/uid/TP40014097-CH8-ID107): 344 | 345 | **Incorrect** 346 | ```swift 347 | let users: Array 348 | let usersByName: Dictionary 349 | ``` 350 | **Correct** 351 | ```swift 352 | let users: [String] 353 | let usersByName: [String: User] 354 | ``` 355 | - **Trailing Comma** 356 | For array and dictionary literals, unless the literal is very short, split it into multiple lines, with the opening symbols on their own line, each item or key-value pair on its own line, and the closing symbol on its own line. Put a trailing comma after the last item or key-value pair to facilitate future insertion/editing. Xcode will handle alignment sanely. 357 | 358 | **Incorrect** 359 | ```swift 360 | let anArray = [ 361 | object1, 362 | object2, 363 | object3 //no trailing comma 364 | ] 365 | 366 | let aDictionary = ["key1": value1, "key2": value2] //how can you even read that?! 367 | ``` 368 | **Correct** 369 | ```swift 370 | let anArray = [ 371 | object1, 372 | object2, 373 | object3, 374 | ] 375 | 376 | let aDictionary = [ 377 | "key1": value1, 378 | "key2": value2, 379 | ] 380 | ``` 381 | 382 | ## 7. Typealiases 383 | - Create `typealiases` to give semantic meaning to commonly used datatypes and closures. 384 | 385 | ```swift 386 | typealias IndexRange = Range 387 | typealias JSONObject = [String: AnyObject] 388 | typealias APICompletion = (jsonResult: [JSONObject]?, error: NSError?) -> Void 389 | typealias BasicBlock = () -> Void 390 | ``` 391 | 392 | ## 8. Switch Statements 393 | - Use multiple values on a single `case` where it is appropriate: 394 | 395 | ```swift 396 | var someCharacter: Character 397 | ... 398 | 399 | switch someCharacter { 400 | case "a", "e", "i", "o", "u": 401 | print("\(someCharacter) is a vowel") 402 | ... 403 | } 404 | ``` 405 | 406 | ## 9. Loops 407 | - Use the `enumerated()` function if you need to loop over a Sequence and use the index: 408 | 409 | ```swift 410 | for (index, element) in someArray.enumerated() { 411 | ... 412 | } 413 | ``` 414 | - Use `map` when transforming Arrays (`flatMap` for Arrays of Optionals or Arrays of Arrays): 415 | ```swift 416 | let array = [1, 2, 3, 4, 5] 417 | let stringArray = array.map { item in 418 | return "item \(item)" 419 | } 420 | 421 | let optionalArray: [Int?] = [1, nil, 3, 4, nil] 422 | let nonOptionalArray = optionalArray.flatMap { item -> Int? in 423 | guard let item = item else { 424 | return nil 425 | } 426 | 427 | return item * 2 428 | } 429 | 430 | let arrayOfArrays = [array, nonOptionalArray] 431 | let anotherStringArray = arrayOfArrays.flatmap { item in 432 | return "thing \(item)" 433 | } 434 | ``` 435 | - If you have an Array of Arrays and want to loop over all contents, consider a `for in` loop using `joined(separator:)` instead of nested loops: 436 | ```swift 437 | let arraysOfNames = [["Moe", "Larry", "Curly"], ["Groucho", "Chico", "Harpo", "Zeppo"]] 438 | ``` 439 | **Recommended** 440 | ```swift 441 | for name in arraysOfNames.joined() { 442 | print("\(name) is an old-timey comedian") 443 | } 444 | ``` 445 | **Discouraged** 446 | ```swift 447 | for names in arraysOfNames { 448 | for name in names { 449 | print("\(name) is an old-timey comedian") 450 | } 451 | } 452 | ``` 453 | 454 | ## 10. Closures 455 | - **Trailing Closure Syntax** 456 | - Use trailing closure syntax when the only or last argument to a function or method is a closure. 457 | 458 | ```swift 459 | //a function that has a completion closure/block 460 | func registerUser(user: User, completion: (Result) -> Void) 461 | ``` 462 | **Incorrect** 463 | ```swift 464 | UserAPI.registerUser(user, completion: { result in 465 | if result.success { 466 | ... 467 | } 468 | }) 469 | ``` 470 | **Correct** 471 | ```swift 472 | UserAPI.registerUser(user) { result in 473 | if result.success { 474 | ... 475 | } 476 | } 477 | ``` 478 | - Omit the empty parens () when the only argument is a closure. 479 | 480 | **Incorrect** 481 | ```swift 482 | let doubled = [2, 3, 4].map() { $0 * 2 } 483 | ``` 484 | **Correct** 485 | ```swift 486 | let doubled = [2, 3, 4].map { $0 * 2 } 487 | ``` 488 | 489 | ## 11. Constants 490 | - Prefer declaring constants outside the scope of a class to give them static storage. 491 | - When creating a shared constants file (ex. Constants.swift), use `struct`s to group related constants together. The name of the `struct` should be singular, and each field should be written using camelCase. 492 | - Be wary of large constants files as they can become unmanageable over time. Refactor related parts of the main constants file into separate files for that situation. 493 | 494 | ```swift 495 | struct SegueIdentifier { 496 | static let onboarding = "OnboardingSegue" 497 | static let login = "LoginSegue" 498 | static let logout = "LogoutSegue" 499 | } 500 | 501 | struct StoryboardIdentifier { 502 | static let main = "Main" 503 | static let onboarding = "Onboarding" 504 | static let settings = "Settings" 505 | } 506 | 507 | print(SegueIdentifier.login) // "LoginSegue" 508 | ``` 509 | - Where appropriate, constants can also be grouped using an `enum` with a `rawValue` type that is relevant to the type you need to work with 510 | 511 | ```swift 512 | enum UserJSONKeys: String { 513 | case username 514 | case email 515 | case role 516 | // Explicitly defined rawValue 517 | case identifier = "id" 518 | ... 519 | } 520 | 521 | print(UserJSONKeys.username.rawValue) // "username" 522 | print(UserJSONKeys.identifier.rawValue) // "id" 523 | 524 | guard let url = URL(string: "http://www.example.com") else { 525 | return 526 | } 527 | 528 | let mutableURLRequest = NSMutableURLRequest(url: url) 529 | mutableURLRequest.HTTPMethod = HTTPMethods.POST.rawValue 530 | print(mutableURLRequest.httpMethod) // "POST" 531 | ``` 532 | 533 | ## 12. Classes vs Structs 534 | - Most of your custom data types should be classes. 535 | - Some situations where you may want to use `struct`s: 536 | - When creating simple, lightweight data types. 537 | - When creating types that are composed of other value types. 538 | - When you don't need inheritance. 539 | - Refer to the [Swift Programming Language Guidlines](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID82) for detailed info on this topic. 540 | 541 | ## 13. Tips & Tricks 542 | - To align code in Xcode, select the block of code you want to Align and then press `ctrl` + `i`. 543 | 544 | 545 | ## Resources: 546 | 547 | - [Swift.org - API Design Guidelines](https://swift.org/documentation/api-design-guidelines/) 548 | - [nshipster.com - Swift Documentation](http://nshipster.com/swift-documentation/) 549 | - [Futurice - ios-good-practices](https://github.com/anasamanp/ios-good-practices) 550 | - [Vokal Engineering - Swift Coding Standards](https://engineering.vokal.io/iOS/CodingStandards/Swift.md.html#declaring-variables) 551 | - [RW - Swift Style Guide](https://github.com/anasamanp/swift-style-guide) 552 | - [The Swift Programming Language](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html) 553 | 554 | 555 | 556 | 557 | -------------------------------------------------------------------------------- /organize-by-functionality.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anas-p/iOS-Best-Practices-Coding-Style/e674e13e8c2111b209bb9c9f62c81b24d7b27a3a/organize-by-functionality.jpeg --------------------------------------------------------------------------------