291

How could I split a string over multiple lines such as below?

var text:String = "This is some text
                   over multiple lines"
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Andrew Deniszczyc
  • 3,298
  • 3
  • 19
  • 16
  • To automagically convert lines into a multiline string, see my answer on this slightly related thread [How can you implement this multiline string literal macro in Swift?](http://stackoverflow.com/a/31881064/1548472) – holroy Aug 07 '15 at 15:10
  • [Swift version](http://stackoverflow.com/a/35389047/1634890) – Juan Boero Feb 14 '16 at 06:29

17 Answers17

485

Swift 4 includes support for multi-line string literals. In addition to newlines they can also contain unescaped quotes.

var text = """
    This is some text
    over multiple lines
    """

Older versions of Swift don't allow you to have a single literal over multiple lines but you can add literals together over multiple lines:

var text = "This is some text\n"
         + "over multiple lines\n"
akim
  • 8,255
  • 3
  • 44
  • 60
Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
  • 2
    The problem w/that approach is you can easily reach too many 'continued' lines in Swift (as of Xcode 6.2 beta), where it complains the expression is "too complex to be solved in a reasonable amount of time" and to consider breaking it down to simpler expressions. That's ugly but easy enough to accomplish, just wrap sections in parens. – clearlight Dec 07 '14 at 00:02
  • 8
    Don't forget to add a space between the closing quote and the +, otherwise you'll get a "'+' is not a postfix unary operator" error – Orlin Georgiev Apr 07 '15 at 08:20
  • This still works, but you need to manually add the `\n` character. For example, in the REPL: `println("foo\n" + "bar")` prints `foo` and `bar` on separate lines. – Brian Gerstle Jul 08 '15 at 17:41
  • It should be fixed in Xcode 7 "Concatenation of Swift string literals, including across multiple lines, is a guaranteed compile-time optimization, even at -Onone. ," http://adcdownload.apple.com/WWDC_2015/Xcode_7_beta/Xcode_7_beta_Release_Notes.pdf – Kostiantyn Koval Jul 31 '15 at 18:19
  • 2
    Doesn't work for enum case values that use strings :( – Lars Blumberg Oct 28 '15 at 14:54
  • If you need a string that spans several lines, use a multiline string literal—a sequence of characters surrounded by three double quotation marks. (relative to the officer document in section Multiline String Literals: https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html ) – Zgpeace Jan 03 '20 at 04:30
32

I used an extension on String to achieve multiline strings while avoiding the compiler hanging bug. It also allows you to specify a separator so you can use it a bit like Python's join function

extension String {
    init(sep:String, _ lines:String...){
        self = ""
        for (idx, item) in lines.enumerated() {
            self += "\(item)"
            if idx < lines.count-1 {
                self += sep
            }
        }
    }

    init(_ lines:String...){
        self = ""
        for (idx, item) in lines.enumerated() {
            self += "\(item)"
            if idx < lines.count-1 {
                self += "\n"
            }
        }
    }
}



print(
    String(
        "Hello",
        "World!"
    )
)
"Hello
World!"

print(
    String(sep:", ",
        "Hello",
        "World!"
    )
)
"Hello, World!"
Blakedallen
  • 664
  • 1
  • 8
  • 23
mcornell
  • 768
  • 1
  • 6
  • 15
  • 2
    These methods are perfect. Even in the latest 1.2 Swift release long literals compile very slowly, and these methods avoid that overhead. – phatmann Mar 19 '15 at 21:06
  • 2
    For anyone using Swift 2, `enumerate(lines)` is now `lines.enumerate()` – Jedidja Sep 30 '15 at 19:47
  • 2
    @mcornell This is nice, but doesn't `joinWithSeparator` do essentially the same thing? `["Hello", "World!"].joinWithSeparator(", ")` – Dan Loewenherz Feb 23 '16 at 15:57
28

This was the first disappointing thing about Swift which I noticed. Almost all scripting languages allow for multi-line strings.

C++11 added raw string literals which allow you to define your own terminator

C# has its @literals for multi-line strings.

Even plain C and thus old-fashioned C++ and Objective-C allow for concatentation simply by putting multiple literals adjacent, so quotes are collapsed. Whitespace doesn't count when you do that so you can put them on different lines (but need to add your own newlines):

const char* text = "This is some text\n"
                   "over multiple lines";

As swift doesn't know you have put your text over multiple lines, I have to fix connor's sample, similarly to my C sample, explictly stating the newline:

var text:String = "This is some text \n" +
                  "over multiple lines"
Community
  • 1
  • 1
Andy Dent
  • 17,578
  • 6
  • 88
  • 115
  • 4
    I'm fairly sure there are limitations in this. I have tried splitting a string over 13 lines (It's a multi line info text). Not only did it fail to finish compiling, but it brought my Mac to its knees. As I say, I can't categorically say this is an issue, but beware, the impact is pretty bad. – Derek Knight Jun 08 '14 at 06:36
  • I've crashed multiple times even before compiling. I think the "SourceKitService" process that is responsible for syntax highlight and code completion (I suppose) is responsible for this crashes as well. – Paweł Brewczynski Jul 15 '14 at 16:01
  • @DerekKnight That's a compiler bug, not a language limitation. If it still persists, you should file a Radar. – radex Aug 25 '14 at 09:29
  • @bluesm FYI: SourceKit is a separate process, so it can't crash Xcode. It does syntax highlighting and code completion, correct, but at the moment, the compilation itself lives in Xcode's process — that's why a compiler bug takes down Xcode with itself sometimes :( – radex Aug 25 '14 at 09:31
18

Multi-line strings are possible as of Swift 4.0, but there are some rules:

  1. You need to start and end your strings with three double quotes, """.
  2. Your string content should start on its own line.
  3. The terminating """ should also start on its own line.

Other than that, you're good to go! Here's an example:

let longString = """
When you write a string that spans multiple
lines make sure you start its content on a
line all of its own, and end it with three
quotes also on a line of their own.
Multi-line strings also let you write "quote marks"
freely inside your strings, which is great!
"""

See what's new in Swift 4 for more information.

TwoStraws
  • 12,862
  • 3
  • 57
  • 71
17

As pointed out by litso, repeated use of the +-Operator in one expression can lead to Xcode Beta hanging (just checked with Xcode 6 Beta 5): Xcode 6 Beta not compiling

An alternative for multiline strings for now is to use an array of strings and reduce it with +:

var text = ["This is some text ",
            "over multiple lines"].reduce("", +)

Or, arguably simpler, using join:

var text = "".join(["This is some text ",
                    "over multiple lines"])
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Jonas Reinsch
  • 171
  • 1
  • 5
10

Swift 4 has addressed this issue by giving Multi line string literal support.To begin string literal add three double quotes marks (”””) and press return key, After pressing return key start writing strings with any variables , line breaks and double quotes just like you would write in notepad or any text editor. To end multi line string literal again write (”””) in new line.

See Below Example

     let multiLineStringLiteral = """
    This is one of the best feature add in Swift 4
    It let’s you write “Double Quotes” without any escaping
    and new lines without need of “\n”
    """

print(multiLineStringLiteral)
Nareshkumar Nil
  • 101
  • 1
  • 5
6

Swift:

@connor is the right answer, but if you want to add lines in a print statement what you are looking for is \n and/or \r, these are called Escape Sequences or Escaped Characters, this is a link to Apple documentation on the topic..

Example:

print("First line\nSecond Line\rThirdLine...")
Juan Boero
  • 6,281
  • 1
  • 44
  • 62
  • 6
    This isn't what anyone wants. We want to be able to be able to have line wraps in the **source code** for the string literals, not (necessarily) have line breaks in the **rendered output**. This was pretty clear in the original question, I think. People with positive scores obviously understood. People with negative scores obviously did not. – ArtOfWarfare Apr 10 '16 at 20:57
  • 6
    @ArtOfWarfare this is the answer I was looking for and this page was the top result when doing a search for "new line swift string". Obviously, it's not as obvious as you say. – John R Perry Oct 29 '16 at 15:26
4

Adding to @Connor answer, there needs to be \n also. Here is revised code:

var text:String = "This is some text \n" +
                  "over multiple lines"
Tamil Selvan C
  • 19,913
  • 12
  • 49
  • 70
Pandurang Yachwad
  • 1,695
  • 1
  • 19
  • 29
3

The following example depicts a multi-line continuation, using parenthesis as a simple workaround for the Swift bug as of Xcode 6.2 Beta, where it complains the expression is too complex to resolve in a reasonable amount time, and to consider breaking it down into smaller pieces:

    .
    .
    .
    return String(format:"\n" +
                    ("    part1:    %d\n"    +
                     "    part2:    %d\n"    +
                     "    part3:  \"%@\"\n"  +
                     "    part4:  \"%@\"\n"  +
                     "    part5:  \"%@\"\n"  +
                     "    part6:  \"%@\"\n") +
                    ("    part7:  \"%@\"\n"  +
                     "    part8:  \"%@\"\n"  +
                     "    part9:  \"%@\"\n"  +
                     "    part10: \"%@\"\n"  +
                     "    part12: \"%@\"\n") +
                     "    part13:  %f\n"     +
                     "    part14:  %f\n\n",
                    part1, part2, part3, part4, part5, part6, part7, part8, 
                    part9, part10, part11, part12, part13, part14)
    .
    .
    .
clearlight
  • 12,255
  • 11
  • 57
  • 75
2

A little extension I wrote.

extension String {

    init(swiftLintMultiline strings: String...) {
        self = strings.reduce("", +)
    }
}

You can use it like so:

String(swiftLintMultiline:
    "Lorem ipsum dolor sit amet, consectetur adipiscing",
    "elit. Ut vulputate ultrices volutpat. Vivamus eget",
    "nunc maximus, tempus neque vel, suscipit velit.",
    "Quisque quam quam, malesuada et accumsan sodales,",
    "rutrum non odio. Praesent a est porta, hendrerit",
    "lectus scelerisque, pharetra magna. Proin id nulla",
    "pharetra, lobortis ipsum sit amet, vehicula elit. Nulla",
    "dapibus ipsum ipsum, sit amet congue arcu efficitur ac. Nunc imperdi"
)
ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
0

You can using unicode equals for enter or \n and implement them inside you string. For example: \u{0085}.

Tamil Selvan C
  • 19,913
  • 12
  • 49
  • 70
hooman
  • 11
0

Another way if you want to use a string variable with some predefined text,

var textFieldData:String = "John"
myTextField.text = NSString(format: "Hello User, \n %@",textFieldData) as String
myTextField.numberOfLines = 0
Zoran777
  • 564
  • 2
  • 7
  • 25
0

Sample

var yourString = "first line \n second line \n third line"

In case, you don't find the + operator suitable

Alex Nolasco
  • 18,750
  • 9
  • 86
  • 81
Danielle Cohen
  • 629
  • 8
  • 5
0

One approach is to set the label text to attributedText and update the string variable to include the HTML for line break (<br />).

For example:

var text:String = "This is some text<br />over multiple lines"
label.attributedText = text

Output:

This is some text
over multiple lines

Hope this helps!

B-Rad
  • 353
  • 3
  • 11
0

Here's a code snippet to split a string by n characters separated over lines:

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {

        let str = String(charsPerLine: 5, "Hello World!")
        print(str) // "Hello\n Worl\nd!\n"

    }
}

extension String {

    init(charsPerLine:Int, _ str:String){

        self = ""
        var idx = 0
        for char in str {
            self += "\(char)"
            idx = idx + 1
            if idx == charsPerLine {
                self += "\n"
                idx = 0
            }
        }

    }
}
Michael N
  • 436
  • 5
  • 6
0

Here's a simple implementation (Swift 5.4+) using a resultBuilder to clean up the syntax a bit!

@resultBuilder
public struct StringBuilder {
    public static func buildBlock(_ components: String...) -> String {
        return components.reduce("", +)
    }
}

public extension String {
    init(@StringBuilder _ builder: () -> String) {
        self.init(builder())
    }
}

Usage:

String {
    "Hello "
    "world!"
} 
// "Hello world!"
Quinn
  • 26
  • 5
-3

I tried several ways but found an even better solution: Just use a "Text View" element. It's text shows up multiple lines automatically! Found here: UITextField multiple lines

Community
  • 1
  • 1
  • (just so you know, the downvotes are probably because the question was about formatting in code, not in the UI… and providing a code sample in your answer would probably have made this more apparent) – benc Jun 22 '20 at 12:08