6

Is there an alternate syntax for strings in Swift ? I need to copy/paste blocks of text including lots of quotes and escaping them each time is kind of a pain.

I'm looking for something like PHP's heredoc syntax, or Python's triple quoted strings. Similar to this question, but I don't care about newlines, I just need it to ignore quotes and backslashes.

Here's a concrete example of the disaster I'm facing right now :

let pattern = "(?:\["(this|is|a|pain|to|escape|properly)+)",0(?:,\[10\])?\])" // that makes me sad
let json = "window.google.ac.h(["this",[["is",0],["even",0],["worse",0]],{"q":"...","k":1}])" // that makes me cry

Thanks.

  • Would it make any sense to put them in a string resource or a plist file instead? That's often a good solution to this category of problem. – Matt Gibson Dec 10 '14 at 22:34
  • @MattGibson well, I'm just using this in playgrounds for debugging, I'm not sure if they can even access resources. For the production app the data comes from a web service so it isn't an issue. –  Dec 10 '14 at 22:37
  • You can [read resource files from a playground](http://stackoverflow.com/questions/24245916/how-can-i-read-a-file-in-a-swift-playground)—you can store the resource files alongside the playground file and load things from there just fine. Of course, I don't know how much of a pain that would be for your particular workflow! – Matt Gibson Dec 10 '14 at 22:39
  • @MattGibson that would indeed break my workflow badly... for right now I'll just deal with the manual escaping but I'd love to see a solution to this. –  Dec 10 '14 at 22:42
  • You should write a Services Menu extension that will escape selected text, or whatever's in the clipboard. I'm sure other people would like to see one :) – Matt Gibson Dec 10 '14 at 22:52
  • @MattGibson I'd love to do so, but my Swift experience is... well... nonexistent so that's going to be tough. :/ –  Dec 10 '14 at 23:03
  • 1
    Well, you don't need Swift to do it :D I just [hacked something up quickly](http://gothick.org.uk/2014/12/10/a-quick-hack-to-quote-swift-strings-in-a-playground/) that might help you, and also give you an example of how to build a Services menu :D – Matt Gibson Dec 11 '14 at 00:06
  • @MattGibson awesome, thanks ! And I said Swift because a quick search for "service menu" brought me to [this](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/SysServices/introduction.html#//apple_ref/doc/uid/10000101-SW1) and it looks long and scary. :o –  Dec 11 '14 at 00:10

3 Answers3

6

As with Objective C, there's no syntax for this in the language. Strings just have to be escaped, at the moment, at least. The alternative is to load the string from a resource file.

I'd raise a bug report with Apple on this one; it would be helpful for the language, more so than with Objective C, for just the reasons you're finding: Swift can be executed more dynamically, in a playground/REPL, so there's more reason to want to paste arbitrary stuff into string constants while you're playing.

Addendum: As an exercise in quick hacking, I just knocked up a quick and dirty Services Menu item in Automator for quoting strings in place in a playground. That's beyond the scope of this Stack Overflow answer, but I documented it on my blog.

Community
  • 1
  • 1
Matt Gibson
  • 37,886
  • 9
  • 99
  • 128
  • 1
    There's a reason you haven't mentioned for why heredoc syntax would be good; at present, constructing a long string by "adding" strings together in code brings Swift completely to its knees. The _only_ way I've found to load a paragraph of complex text into a variable is to get it from a resource file. Doing it in source code isn't just clumsy - it literally breaks the source code, by blowing up the compiler. – matt Dec 10 '14 at 23:16
  • 1
    Yup, we need more people to file radars on this. Swift's poor handling of large strings is a massive problem and needs to be fixed. Apple is obviously aware of it, but more complaints will result in a quicker solution. Which of these do you prefer? https://gist.github.com/abhibeckert/b12e19a85c4806296c7e – Abhi Beckert Dec 11 '14 at 00:11
  • @matt I'd not actually needed to do that, so I hadn't noticed the compiler creaking under the weight. But there have been times in pretty much any language I've used that lacks a heredoc syntax where I've really been annoyed by that lack. I'll put "file a radar" on my todo list for tomorrow. – Matt Gibson Dec 11 '14 at 00:23
6

This feature was added to Swift in 2017. (SE 0168 Multi-Line String Literals)

Swift Documentation: Welcome to Swift: Simple Values says:

Use three double quotation marks (""") for strings that take up multiple lines. Indentation at the start of each quoted line is removed, as long as it matches the indentation of the closing quotation marks. For example:

let quotation = """
I said "I have \(apples) apples."
And then I said "I have \(apples + oranges) pieces of fruit."
"""

According to a comment on Swift three double quotes, "This is brand new to Swift 4 and Xcode 9."

For more details, see Swift Documentation: Language Guide: Strings and Characters: String Literals: Multiline String Literals.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
3

Swift doesn't support it, but C++11 does. And we can easily import it to Swift, as NSStrings.

StringConst.h:

#import <Foundation/Foundation.h>

extern NSString *const STR_PATTERN;
extern NSString *const STR_JSON;

StringConst.mm:

#import "StringConst.h"

NSString * const STR_PATTERN = @R"""((?:\["(this|is|a|pain|to|escape|properly)+)",0(?:,\[10\])?\]))""";
NSString * const STR_JSON = @R"""(window.google.ac.h(["this",[["is",0],["even",0],["worse",0]],{"q":"...","k":1}]))""";

<Target>-Bridging-Header.h:

#import "StringConst.h"

AnySwift.swift:

println(STR_PATTERN)
println(STR_JSON)

Added:

To use this in Playground, you have to create a Framework project, and Playground file in it.

sceenshot

rintaro
  • 51,423
  • 14
  • 131
  • 139
  • 2
    Sadly, this isn't much help in a playground, as far as I can see. Let's hope Swift catches up to C++11 faster than C++ did... – Matt Gibson Dec 11 '14 at 12:42
  • I think this can still be a useful technique, and it's definitely a valid answer to the original question. – Matt Gibson Dec 11 '14 at 13:22
  • 1
    @MattGibson we can still use that in Playground :) – rintaro Dec 11 '14 at 13:29
  • Unfortunately this is a bit too much work just to set this up, isn't practical for quick debugging when you add a playground to an existing project. And it would break my workflow if I need to switch back and forth between files just to edit the strings. –  Dec 11 '14 at 13:34