├── .gitignore ├── Custom Operators.playground ├── Pages │ ├── Custom Compound Assignment.xcplaygroundpage │ │ └── Contents.swift │ ├── Custom Emoji Operators.xcplaygroundpage │ │ └── Contents.swift │ ├── Custom Infix.xcplaygroundpage │ │ └── Contents.swift │ ├── Custom Postfix.xcplaygroundpage │ │ └── Contents.swift │ ├── Custom Prefix.xcplaygroundpage │ │ └── Contents.swift │ └── Introduction.xcplaygroundpage │ │ └── Contents.swift └── contents.xcplayground ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /Custom Operators.playground/Pages/Custom Compound Assignment.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | /*: 3 | # Custom Compound Assignment Operator 4 | ### Setup the structures 5 | */ 6 | struct Team { 7 | let title: String 8 | private(set) var members: [Member] 9 | 10 | mutating func add(_ member: Member) { 11 | members.append(member) 12 | } 13 | } 14 | 15 | struct Member: CustomDebugStringConvertible { 16 | let name: String 17 | 18 | var debugDescription: String { name } 19 | } 20 | /*: 21 | ### Adding a member without a custom operator 22 | */ 23 | var team = Team(title: "Developers 🔵🔴⚪️", members: [Member(name: "Antoine 🇳🇱")]) 24 | 25 | let newMember = Member(name: "Donny 🇳🇱") 26 | team.add(newMember) 27 | /*: 28 | ### Setup the custom Compound Assignment Operator += 29 | */ 30 | extension Team { 31 | static func += (lhs: inout Team, rhs: Member) { 32 | lhs.add(rhs) 33 | } 34 | } 35 | /*: 36 | ### Use the custom operator in code 37 | */ 38 | let anotherMember = Member(name: "Vincent 🇫🇷") 39 | team += anotherMember 40 | print(team.members) 41 | //: [Next](@next) 42 | -------------------------------------------------------------------------------- /Custom Operators.playground/Pages/Custom Emoji Operators.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | /*: 3 | # Custom Emoji Operator 4 | ### Setup the custom operator 5 | */ 6 | extension String { 7 | static func + (lhs: String, rhs: String) -> String { 8 | switch (lhs, rhs) { 9 | case ("🛹", "❄️"): 10 | return "🏂" 11 | case ("😬", "❄️"): 12 | return "🥶" 13 | case ("😢", "🔥"): 14 | return "🥵" 15 | case ("🥕", "🥬"): 16 | return "🥬" 17 | case ("🥬", "🥒"): 18 | return "🥒" 19 | case ("🥒", "🍅"): 20 | return "🥗" 21 | case ("🧔", "💈"): 22 | return "👶🏻" 23 | case ("🦏", "🌈"): 24 | return "🦄" 25 | case ("🔨", "🔧"): 26 | return "🛠" 27 | default: 28 | print("\(lhs) and \(rhs) not matched") 29 | return "⁉️" 30 | } 31 | } 32 | } 33 | /*: 34 | ### Making use of the custom operator 35 | */ 36 | print("🛹" + "❄️") 37 | print("😬" + "❄️") 38 | print("😢" + "🔥") 39 | print("🥕" + "🥬" + "🥒" + "🍅") 40 | print("🧔" + "💈") 41 | print("🦏" + "🌈") 42 | print("🔨" + "🔧") 43 | -------------------------------------------------------------------------------- /Custom Operators.playground/Pages/Custom Infix.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | /*: 3 | # Custom Infix Operator 4 | ### Setup the progress view 5 | */ 6 | let firstNumbers: Set = [1, 4, 5] 7 | let secondNumbers: Set = [1, 4, 6] 8 | /*: 9 | ### Setup the Custom Infix Operator ~ 10 | See [Operator Declarations](https://developer.apple.com/documentation/swift/swift_standard_library/operator_declarations) for all precedence options. 11 | */ 12 | infix operator +-: AdditionPrecedence 13 | extension Set { 14 | static func +- (lhs: Set, rhs: Set) -> Set { 15 | return lhs.union(rhs) 16 | } 17 | } 18 | /*: 19 | ### Use the custom operator in code 20 | */ 21 | let uniqueNumbers = firstNumbers +- secondNumbers 22 | print(uniqueNumbers) 23 | //: [Next](@next) 24 | -------------------------------------------------------------------------------- /Custom Operators.playground/Pages/Custom Postfix.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | /*: 3 | # Custom Postfix Operator 4 | ### Setup the progress view 5 | */ 6 | let progressView = UIProgressView(progressViewStyle: .bar) 7 | progressView.trackTintColor = .black 8 | progressView.progressTintColor = .orange 9 | /*: 10 | ### Setup the custom prefix operator ~ 11 | */ 12 | import UIKit 13 | postfix operator % 14 | postfix func % (percentage: Int) -> Float { 15 | return (Float(percentage) / 100) 16 | } 17 | /*: 18 | ### Use the custom operator in code 19 | */ 20 | progressView.progress = 20% 21 | //: [Next](@next) 22 | -------------------------------------------------------------------------------- /Custom Operators.playground/Pages/Custom Prefix.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | /*: 2 | # Custom Prefix Operator 3 | ### Setup the formatting 4 | */ 5 | import Foundation 6 | let currencyFormatter = NumberFormatter() 7 | currencyFormatter.numberStyle = .currency 8 | currencyFormatter.locale = Locale.current 9 | 10 | let priceString = currencyFormatter.string(from: 9999.99)! 11 | print(priceString) // Displays $9,999.99 in the current locale, for example $ dollars. 12 | /*: 13 | ### Setup the custom prefix operator ~ 14 | */ 15 | prefix func ~ (value: NSNumber) -> String { 16 | let currencyFormatter = NumberFormatter() 17 | currencyFormatter.numberStyle = .currency 18 | currencyFormatter.locale = Locale.current 19 | 20 | return currencyFormatter.string(from: value)! 21 | } 22 | /*: 23 | ### Use the custom operator in code 24 | */ 25 | let decimalInputPrice: String = ~843.32 26 | print(decimalInputPrice) // Prints: $843.32 27 | 28 | let intInputPrice: String = ~300 29 | print(intInputPrice) // Prints: $300.00 30 | //: [Next](@next) 31 | -------------------------------------------------------------------------------- /Custom Operators.playground/Pages/Introduction.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | /*: 2 | # Custom Operators Playground 3 | This playground demonstrates custom operators in Swift. 4 | 5 | - Related blogpost: [Custom Operators in Swift with practical code examples](https://www.avanderlee.com/swift/custom-operators-swift/) 6 | 7 | Use the footer navigation or directly jump to any of the operators: 8 | 9 | - [Custom Prefix](Custom%20Prefix) 10 | - [Custom Postfix](Custom%20Postfix) 11 | - [Custom Infix](Custom%20Infix) 12 | - [Custom Compound Assignment](Custom%20Compound%20Assignment) 13 | - [Custom Emoji Operators](Custom%20Emoji%20Operators) 14 | 15 | [Next](@next) 16 | */ 17 | -------------------------------------------------------------------------------- /Custom Operators.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Antoine van der Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Custom Swift Operators 2 | ![Swift Version](https://img.shields.io/badge/Swift-5.3-F16D39.svg?style=flat) [![Twitter](https://img.shields.io/badge/twitter-@Twannl-blue.svg?style=flat)](https://twitter.com/twannl) 3 | 4 | Demonstrating custom Swift operators. Including prefix, postfix, infix, and compound assignment operators. Related blogpost: [Custom Operators in Swift with practical code examples](https://www.avanderlee.com/swift/custom-operators-swift/). 5 | 6 | ## Included in this project 7 | - [x] Infix operator 8 | - [x] Prefix operator 9 | - [x] Postfix operator 10 | - [x] Compound Assignment Operator 11 | - [x] Emoji Operators 12 | 13 | ## Contributing 14 | If you have a great example of a custom operator you think we can all benefit from, feel free to open a PR with a new Playground page. 15 | 16 | ## Communication 17 | 18 | - If you **found a bug**, open an [issue](https://github.com/AvdLee/appstoreconnect-swift-sdk/issues). 19 | - If you **have a feature request**, open an [issue](https://github.com/AvdLee/appstoreconnect-swift-sdk/issues). 20 | - If you **want to contribute**, submit a [pull request](https://github.com/AvdLee/appstoreconnect-swift-sdk/pulls). 21 | 22 | ## License 23 | 24 | **Custom Swift Operators** is available under the MIT license, and uses source code from open source projects. See the [LICENSE](https://github.com/AvdLee/CoreDataBestPractices/blob/main/LICENSE) file for more info. 25 | 26 | ## Author 27 | 28 | This project is originally created by [Antoine van der Lee](https://www.twitter.com/twannl) based on experienced from developing [Collect by WeTransfer](https://collect.bywetransfer.com) and writing posts at [SwiftLee](https://www.avanderlee.com). A detailed explanation of custom operators can be found on his blog [Custom Operators in Swift with practical code examples](https://www.avanderlee.com/swift/custom-operators-swift/). 29 | --------------------------------------------------------------------------------