How do I access program arguments in Swift?

17,393

Solution 1

Process was just renamed into CommandLine (since Swift 3.0 August 4 snapshot)

let arguments = CommandLine.arguments

(for some reason this wasn't mentioned on the changelog)

Solution 2

Process.arguments is your friend!

Fortunately this is much easier, and built in: no importing anything, no getting your hands dirty with C, objective or otherwise.

Consider this, let's call it args.swift:

Swift 2 version:

var c = 0;
for arg in Process.arguments {
    println("argument \(c) is: \(arg)")
    c++
}

Swift 3 version:

var c = 0;
for arg in CommandLine.arguments {
    print("argument \(c) is: \(arg)")
    c += 1
}

We can compile and run it like this:

$ swift -o args args.swift && ./args fee fi fo fum
argument 0 is: ./args
argument 1 is: fee
argument 2 is: fi
argument 3 is: fo
argument 4 is: fum

Note that the first argument is the program name, as you might expect.

It seems every argument is a String, as you might also expect.

I hope very much that Process becomes more useful as Swift matures, but right now it seems to only give you the arguments. Which is a lot, if you're trying to write a pure-Swift program.

Solution 3

As soon as your app is up I'd use the process info:

let args = NSProcessInfo.processInfo().arguments
print(args)

Nothing unsafe there, very convenient.

Note that you have to import Foundation (or Cocoa / UIKit).

Solution 4

For Swift 3 you can use this code:

let argc = CommandLine.argc
let argv = UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc))

which is equivalent of argc and argv parameters used in Objective-C main function:

int main(int argc, char *argv[])

For older versions of Swift, you can use Process.argc and Process.unsafeArgv or C_ARGC and C_ARGV.

You can pass this variables to UIApplicationMain function in iOS app:

Swift 3:

let argc = CommandLine.argc
let argv = UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc))
UIApplicationMain(argc, argv, nil, NSStringFromClass(AppDelegate.self))

previous Swift versions:

UIApplicationMain(Process.argc, Process.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))

or:

UIApplicationMain(C_ARGC, C_ARGC, nil, NSStringFromClass(AppDelegate.self))

Objective-C:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
Share:
17,393
zneak
Author by

zneak

No longer contributing to Stack Overflow.

Updated on June 05, 2022

Comments

  • zneak
    zneak about 2 years

    C and derivatives have argc and argv (and envp) parameters to their entry point functions, but Swift doesn't have one proper: top-level code is just code and it doesn't have parameters.

    How can one access the equivalent of argc and argv in a Swift program?

  • Getz
    Getz about 10 years
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post.
  • Waruna
    Waruna about 10 years
    Added a extra explanation
  • Brad Dwyer
    Brad Dwyer about 10 years
    Looks like you have to manually put in import Foundation for this to work else it will fail with error: use of unresolved identifier 'NSProcessInfo'
  • Joe
    Joe about 10 years
    You can also use swift -i to run Swift code like a Python or Ruby script; along with Process.arguments Swift makes for a promising scripting language.
  • alaroldai
    alaroldai almost 10 years
    Is there any documentation for Process?
  • David H
    David H almost 10 years
    You can just import Darwin if you don't want any ObjectiveC code.
  • David H
    David H almost 10 years
    Ditto above comment - where can I find info on Process?
  • Daij-Djan
    Daij-Djan almost 10 years
    @DavidH don't get you
  • David H
    David H almost 10 years
    @Daij-Djan sorry missed your question - "import Darwin" should import just the C libraries, and thus no ObjectiveC libraries. Then, it should be possible to use "Process" as others have mentioned in other answers.
  • Daij-Djan
    Daij-Djan almost 10 years
    NSProcessInfo is objC and in foundation
  • cabbey
    cabbey over 8 years
  • leogdion
    leogdion almost 8 years
    This is the correct answer now with Xcode 8 Beta 6. This one among many changes I note here: brightdigit.com/blog/16/08/17/updating-for-xcode-8-beta-6
  • zneak
    zneak over 7 years
    ...or, more simply, CommandLine.arguments.
  • Darrarski
    Darrarski over 7 years
    @zneak sure, it's the simplest way, but you can't pass it into UIApplicationMain function, you have to use mentioned UnsafeMutableRawPointer instead.
  • zneak
    zneak over 7 years
    I see. I only do macOS development. On our side, merely having an app delegate will cause the compiler to create a main function that calls NSApplicationMain. I was assuming that something similar happens on iOS.
  • Jan ATAC
    Jan ATAC almost 7 years
    Typo error ? swiftc -o args... instead of swift -o args ... ?