Swift: Extending functionality of print() function
You can overshadow the print
method from the standard library:
public func print(items: Any..., separator: String = " ", terminator: String = "\n") {
let output = items.map { "*\($0)" }.joined(separator: separator)
Swift.print(output, terminator: terminator)
}
Since the original function is in the standard library, its fully qualified name is Swift.print
Overriding Swift.print() or sharing function across all modules
Nope, it's not possible, if you want to use a function from a different module, you have to import that module.
The default print
function is part of the Swift
module, which is automatically (implicitly) imported in all Swift files, this is why it's available everywhere without explicitly importing the module.
How to swizzle Swift.print(items:separator:terminator)
Method swizzling is an Objective-C feature that enables you to exchange implementation of a method at runtime. For that, you need an @objc
object that inherits from NSObject
. And you need a method.
Swift.print
is not a method. It's a function declared in the Swift
module. We can say it's global but it's not really global. It's defined inside module Swift
which is imported automatically to every Swift code, therefore you can use it without the Swift.
prefix.
In summary, there is no way to swizzle Swift.print
.
What you can do is to hide that function using your own implementation, that is, if you declare a function with the same name in your own module, then when print
is used, the compiler will prefer your function instead because functions in the current module are preferred over functions in other modules (including Swift.
module).
public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
let output = items.map { "\($0)" }.joined(separator: separator)
Swift.print(output, terminator: terminator)
}
You can any logic you want in there.
It's actually very common to use this to remove logging from production, e.g.:
#if !DEBUG
func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {}
func debugPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") {}
#endif
See Remove println() for release version iOS Swift for more details.
Essentially, you could hide the whole Swift
module by redeclaring it inside your module, e.g. as an enum
, therefore disabling calls to Swift.print
:
enum Swift {
public static func print(_ items: Any..., separator: String = " ", terminator: String = " ") {
// do something
}
}
However, I would generally advise against this because it will be hard to solve any naming conflicts with the standard library inside the Swift.
module.
In general, I would advise to implement your custom logging system and enforce its usage by other means, e.g. code reviews or linting rules (e.g. swiftlint).
Turn Swift function into extension for reuse
Extension:
extension String {
func removeCharacters(from characterSet: CharacterSet) -> String {
let filteredString = self.unicodeScalars.filter { !characterSet.contains($0) }
return String(String.UnicodeScalarView(filteredString))
}
}
Usage:
var string1 = "1122 ;4B"
print(string1.removeCharacters(from: [" ", ";", ".", "!", "/"]))
Use removeCharacters
as default parameter:
extension String {
func removeCharacters(from characterSet: CharacterSet = [" ", ";", ".", "!", "/"]) -> String {
let filteredString = self.unicodeScalars.filter { !characterSet.contains($0) }
return String(String.UnicodeScalarView(filteredString))
}
}
var string1 = "1122 ;4B"
print(string1.removeCharacters())
Trying to display different print() messages depending on the number variable i.e. Temperature
Beside the fact that you are using the wrong operator for comparison =
instead of ==
, and if you would like to check if a range contain a value what you need is the pattern matching operator ~=
. i.e: if 0...<21 ~= temp {
but what you are really looking for is a switch:
let temp = 76
switch temp {
case .min ..< 0: print("Too Cold for Outdoors")
case 0 ..< 21: print("Very Cold Weather")
case 21 ..< 41: print("Cold")
case 41 ..< 61: print("Normal")
case 61 ..< 81: print("Nice")
case 81 ..< 91: print("Warm")
default: print("Hot")
}
This will print:
Nice
Related Topics
Type Conversion When Using Protocol in Swift
Make Code With Firebase Asynchronous
Try, Try! & Try? What's the Difference, and When to Use Each
How to Silence a Warning in Swift
Swap Rootviewcontroller With Animation
Swift Xcode Index Freezing or Slow
How to Document the Parameters of a Function'S Closure Parameter in Swift 3
How to Access Program Arguments in Swift
Get Button Pressed Id on Swift Via Sender
Programmatically Screenshot | Swift 3, Macos
Different Ways to Initialize a Dictionary in Swift
How to Create a View-Based Nstableview Purely in Code
Swift Semantics Regarding Dictionary Access
Obervableobject Being Init Multiple Time, and Not Refreshing My View
How to Do If Pattern Matching with Multiple Cases
How to Perform an Action Only After Data Are Downloaded from Firebase