20

Is it possible to extend the functionality of a Swift function? I would like appnd a single character onto every print() function in my program without having to create a brand new function and renaming every instance of print(). Is it possible to create an extension that will append an '*' onto every print instance?

The purpose of this is to create a way of flushing out all of the extra information that XCODE adds into the debugger. I am using print statements to check on the progress and success of different parts of my code, but XCODE fills in thousands of lines of excess info in seconds that quickly cover up my specific statements.

What I want to do:

print("Hello world!")
//Psuedo code:
Extension print(text: String) {
    let newText = "*\(text)"
    return newText
}

Output: *Hello World!

I will then filter the Xcode debugging output for asterisks. I have been doing this manually

DeyaEldeen
  • 10,847
  • 10
  • 42
  • 75
Alec O
  • 1,697
  • 1
  • 18
  • 31
  • 4
    If this is in Xcode, have you tried just switching to "Target Output" in the debug window rather than "All Output?" – Rob Napier Aug 18 '16 at 20:53

3 Answers3

31

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

Chackle
  • 2,249
  • 18
  • 34
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • 4
    Is this "overriding"? I think it's just "shadowing" – Alexander Aug 18 '16 at 21:02
  • Where can I place this function so that it is available in all files? And is there a way to use this function without having to add `items:` in such as `print(items: "Hello")` – Alec O Aug 18 '16 at 21:22
  • Make a new `.swift` file and place it there. if you are using Swift 2, you don't have to specify the `item:` label. The code won't work with Swift 3 anyway. – Code Different Aug 18 '16 at 22:45
  • Is there a swift3 solution to this? Because it is xcode8 that is adding all the unwanted extra garbage to the console.... (which seems to be a 'known issue' and is no longer the case with xcode8.1 beta....) My point being, xcode8 and swift3 are like big buddies... This code not working in Swift3 is kinda missing the point. I would love to have a temporary print replacement that works in swift3.... Or maybe I should just go for xcode8.1 beta.... Little unexperienced in the beta-channel, does it replace your stable version of xcode or can the exist next to eachother? – RemyNL Oct 09 '16 at 15:00
  • 5
    I just tried this in swift3/xcode 8.3. You can just add a `_` before items. `public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {...}` – Programus Apr 04 '17 at 01:59
  • It appears that this leads to prefacing each print command, like `Swift.print("Hello world")` Otherwise, Xcode throws an error `Use of 'print' nearly matches global function 'print(_:separator:terminator:)' in module 'Swift'...` – David Nov 07 '17 at 18:41
  • will this work for your entire app or just the one file? – bj97301 Oct 19 '18 at 18:33
21

If we want to cover all cases with custom print we should create new file for example: CustomPrint.swift and then paste this two methods:

SWIFT 5.1

First (according to ThomasHaz answer)

public func print(_ items: String..., filename: String = #file, function : String = #function, line: Int = #line, separator: String = " ", terminator: String = "\n") {
    #if DEBUG
        let pretty = "\(URL(fileURLWithPath: filename).lastPathComponent) [#\(line)] \(function)\n\t-> "
        let output = items.map { "\($0)" }.joined(separator: separator)
        Swift.print(pretty+output, terminator: terminator)
    #else
        Swift.print("RELEASE MODE")
    #endif
}

and second because the first one does't cover dictionary and array printing

public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
        let output = items.map { "\($0)" }.joined(separator: separator)
        Swift.print(output, terminator: terminator)
    #else
        Swift.print("RELEASE MODE")
    #endif
}

Enjoy :)

PiterPan
  • 1,760
  • 2
  • 22
  • 43
20

This code working for me in swift 3

import Foundation

public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    let output = items.map { "\($0)" }.joined(separator: separator)
    Swift.print(output, terminator: terminator)
}

class YourViewController: UIViewController {
}
Nehrulal Hingwe
  • 326
  • 2
  • 9