How to Access Program Arguments in Swift

How do you access command line arguments in Swift?

Apple has released the ArgumentParser library for doing just this:

We’re delighted to announce ArgumentParser, a new open-source library that makes it straightforward — even enjoyable! — to parse command-line arguments in Swift.

https://swift.org/blog/argument-parser/



Swift Argument Parser

https://github.com/apple/swift-argument-parser

Begin by declaring a type that defines the information you need to collect from the command line. Decorate each stored property with one of ArgumentParser's property wrappers, and declare conformance to ParsableCommand.

The ArgumentParser library parses the command-line arguments, instantiates your command type, and then either executes your custom run() method or exits with useful a message.

How do I access program arguments in Swift?

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)

Command line arguments in swift - convert to interger

All arguments are passed as Strings, so if you want to use them as Ints, you need to add the conversion.

Also, argc is an UInt32 and needs to be converted as well so that you can use it as a subscript index.

For example, like so:

for i in 1 ..< Int(CommandLine.argc) {
if let intValue = Int(CommandLine.arguments[i]) {
print("arg:", intValue + 2)
}
}

Giving Command line arguments in Xcode in C program

Pre Xcode 4.x

Right click the executable in your Xcode project and pick "Get Info". Then pick the "arguments" tab and you can set arguments to pass when you run or debug your program from inside Xcode.

Xcode 4.x or later

Go to the Product menu, select "Edit Scheme", then select the arguments tab and add the arguments there.

How can I use getopt with command line arguments in Swift 3?

@Hamish already answered the question and explained how to pass CommandLine.unsafeArgv to getopt() in Swift (and why).

Here is a complete self-contained example how a typical getopt
loop can be implemented in Swift 3:

var aFlag = false
var bFlag = false
var cValue: String?

while case let option = getopt(CommandLine.argc, CommandLine.unsafeArgv, "abc:"), option != -1 {
switch UnicodeScalar(CUnsignedChar(option)) {
case "a":
aFlag = true
case "b":
bFlag = true
case "c":
cValue = String(cString: optarg)
default:
fatalError("Unknown option")
}
}

print(aFlag, bFlag, cValue ?? "?")

Remarks:

  • You can pass a Swift string (here: "abc:") directly to a C
    function expecting a (constant) C string, the compiler will automatically
    generate a temporary UTF-8 representation.
  • getopt() return either -1 (if the argument list is exhausted) or an unsigned char converted to an int. Therefore it is safe to
    convert the return value to CUnsignedChar (which is UInt8 in Swift).
  • while is used (abused?) with pattern matching plus an additional
    boolean condition to implement the typical C pattern

    while ((option = getopt(argc, argv, "abc:")) != -1) { ... }

    in Swift.

How to get the launch arguments while making a command line tool with swift

See the linked question, there’s the answer How do I access program arguments in Swift?

import Foundation

let args = NSProcessInfo.processInfo().arguments;
println(args);

How to open new app with arguments from swift app using terminal command

I'm pretty sure that instead of this

let args:[String] = ["-c","open -n /Applications/test.app","--args aaaa"]

it should be this

let args:[String] = ["-c","open","-n","/Applications/test.app","--args","aaaa"]

Also, you don't really need to go through z shell. You could just call open directly.

task.launchPath = "/usr/bin/open"
let args:[String] = ["-n","/Applications/test.app","--args","aaaa"]

How to get arguments of NSRunningApplication?

The "ps" tool uses sysctl() with KERN_PROCARGS2 to get the arguments of a running process. The following is an attempt to translate the code from adv_cmds-153/ps/print.c to Swift. That file also contains a documentation of the memory layout of the raw argument space and explains how to locate the string arguments in that memory.

func processArguments(pid: pid_t) -> [String]? {

// Determine space for arguments:
var name : [CInt] = [ CTL_KERN, KERN_PROCARGS2, pid ]
var length: size_t = 0
if sysctl(&name, CUnsignedInt(name.count), nil, &length, nil, 0) == -1 {
return nil
}

// Get raw arguments:
var buffer = [CChar](repeating: 0, count: length)
if sysctl(&name, CUnsignedInt(name.count), &buffer, &length, nil, 0) == -1 {
return nil
}

// There should be at least the space for the argument count:
var argc : CInt = 0
if length < MemoryLayout.size(ofValue: argc) {
return nil
}

var argv: [String] = []

buffer.withUnsafeBufferPointer { bp in

// Get argc:
memcpy(&argc, bp.baseAddress, MemoryLayout.size(ofValue: argc))
var pos = MemoryLayout.size(ofValue: argc)

// Skip the saved exec_path.
while pos < bp.count && bp[pos] != 0 {
pos += 1
}
if pos == bp.count {
return
}

// Skip trailing '\0' characters.
while pos < bp.count && bp[pos] == 0 {
pos += 1
}
if pos == bp.count {
return
}

// Iterate through the '\0'-terminated strings.
for _ in 0..<argc {
let start = bp.baseAddress! + pos
while pos < bp.count && bp[pos] != 0 {
pos += 1
}
if pos == bp.count {
return
}
argv.append(String(cString: start))
pos += 1
}
}

return argv.count == argc ? argv : nil
}

There is only a simple error handling: if anything goes wrong, the function returns nil.

For an instance of NSRunningApplication you can then call

processArguments(pid: application.processIdentifier)

How to I access argv and argc in swift?

There are two ways to do this:

  1. The constants C_ARGC and C_ARGV. They are analogous to the argc and argv you'd see in a main() function.
  2. The CommandLine.arguments array will contain all of the arguments to the process. (In Swift 2, CommandLine was called Process)


Related Topics



Leave a reply



Submit