Importing other libraries when using Swift as a scripting language - swift

Heyo. I'm using Swift to make a simple web crawler for fun and practice. I made an Project.swift file and added it to a folder on my desktop. I now want to add SwiftyJSON to my project. I tried putting SwiftyJSON.swift in the same folder and adding import SwiftyJSON on top, but this did nothing. No import statement does not work at all. Is there any way to do this except pasting the whole file to the bottom of my project.swift file, or should I just stick to Python?

You have to start from the file named main.swift - that's your application entry point:
// main.swift
import Foundation
let data = "{\"message\" : \"Hello World\"}".dataUsingEncoding(NSUTF8StringEncoding)
let myJson = JSON(data:data!)
print(myJson["message"])
So you don't have to use include, but you'll need to specify all external dependencies when compiling:
swiftc SwiftyJSON.swift main.swift
./main
If you're using XCode Command Line Tool template, main.swift will be created for you by default, and you'd be able add more .swift files to your project and just use them, no need to use import.

Related

Exporting Package.swift for Swift Package Manager from existing Xcode project

I'm working with Xcode 11.3 on macOS Catalina 10.15.6.
I have an existing Xcode project which builds an app for iOS. I am interested in reusing some of the classes in an interactive session with the swift command line interpreter. The classes I want to work with are Core Data classes which are autogenerated from an Xcode data model and also some classes I've written which work with the Core Data classes. The app has UI screens and makes use of UIKit but I'm not trying to use any of those classes; I'm hoping that I can either compile those classes and then not refer to them, or somehow tell Swift Package Manager to ignore those classes altogether.
What I think I would like to do is to export a Package.swift for the existing Xcode project, such that swift build at the command line would be able to compile all of the project classes, or, failing that, at least the non-UI classes, and then swift run --repl would be able to load the classes via import.
I see a menu item in Xcode to create a new Swift package, but not to export an existing project. Is there a way to export an existing project?
There are no a menu command or utility to convert application to a static library, dynamic framework or swift package since they are different types of projects with different settings etc.
If you want to export a part of your project as a swift package you should make next steps manually:
1. Create Package.swift file in the root of your project
import PackageDescription
let package = Package(
name: “MyLib”,
products: [
.library(name: "MyLib", targets: ["MyLib"])
],
targets: [
.target(name: "MyLib"),
],
...
)
2. Make folder with subfolder ./Sources/MyLib under the projects’s root.
By default swift package structure requires to put all your sources files under Sources/LibraryName folder but you can change it below.
NOTE: you can simplify first two steps by using swift package init and it creates Package.swift, Sources and Test folders etc.
3. Include source files
a) Move the needed files to share from their current locations to MyLib folder.
For instance:
./Classes/MyEntity.swift -> ./Sources/MyLib/MyEntity.swift
Also you have to update locations of the moved files in your Xcode project to leave it compilable.
b) Use path, sources and exclude to point needed source files to your package from their current locations:
.target(name: "MyLib", path: "Classes"),
NOTE: Don't forget to make your classes public to access to them after import your package:
public class MyEntity {
...
}
After all you will have two working projects - old XCode's one and new Swift package.
4. REPL
Now you can use command line interpreter with your swift package:
swift run --repl
import MyLib
let entity = MyEntity()
...

importing a module in Swift

I'm kicking the tires of Swift a little. I'm not using Xcode. I just have a simple .swift file and #!/usr/bin/env swift at the top of the file.
In the file, I have import Blahblah and a file called Blahblah in the same directory.
I get error: no such module 'Blahblah' however when running the .swift file.
How do I import the swift module? Is there something special I need to do?

How to import library into swift code used in CLI?

What I want to do
I want to try to get son file through API by swift library on CLI.
I am using the library, Alamofire, but I can't understand how to import swift library.
Maybe some tasks are needed before import (building? linking?) but I can't find how to document...
Could you teach me how to do it?
Problem
$ swift getAPI.swift
getAPI.swift:1:8: error: no such module 'Alamofire'
import Alamofire
^
Sourcecode
import Alamofire
func getArticles(){
Alamofire.request(.GET, "https://qiita.com/api/v2/items")
.responseJSON { response in
print(response.result.value )
}
}
getArticles()
This should help with running one-off scripts and when using the Swift REPL. However, for building simple tools for the command line, I would recommend using the Swift Package Manager since it takes care of the linking and dependency management for you.
To link your script code to the Alamofire library, the swift compiler has to know where to the library is located. By default it searches /Library/Frameworks, but we can supply options to tell it where else to look. Checking swift --help, we see the following options (among many others).
USAGE: swift [options] <inputs>
OPTIONS:
-F <value> Add directory to framework search path
-I <value> Add directory to the import search path
-L <value> Add directory to library link search path
The directory you supply must to contain the compiled binaries of the libraries you want to import.
To import .swiftmodule binaries, use -I
To import .framework binaries, use -F
For linking to libraries like libsqlite3.0.dylib, use -L
I think Carthage and CocoaPods will build frameworks, whereas the Swift Package Manager will build .swiftmodules. All three should put the binaries in very predictable locations. Different kinds of binaries may all be in the same and that's okay.
Putting it all together, if you build with SPM, your invocation might look like this:
$ swift -I .build/debug/
But if you manage dependencies with Carthage, it might look something like this:
$ swift -F ./Carthage/Build/iOS
For further reading, I found these resources useful:
krakendev.io/blog/scripting-in-swift
realm.io/news/swift-scripting/
Update: The Swift package manager can now take care of this for you as well! If you're writing a script as a package and include a bunch of dependencies, like Alamofire, you can now test them out in the REPL. Just cd into your package directory and launch it using swift run --repl. See the swift.org blog for more details.

Swift REPL: how to import, load, evaluate, or require a .swift file?

In the Swift REPL, how to import (a.k.a. load, evaluate, require) a typical text *.swift file?
I want to use the code from this file: ~/src/Foo.swift
Syntax like this doesn't work: import ~/src/Foo.swift
For comparison:
An equivalent solution in the Swift REPL for a framework is: import Foundation
An equivalent solution in the Ruby REPL for a *.ruby file is: require "~/src/foo"
These are similar questions that are /not/ what I'm asking:
How to use/make a Swift command-line script, executable, module, etc.
How to use/make an XCode playground, project, library, framework, etc.
How to launch the REPL with a pre-existing list of files.
You need to use -I, so if your modulename.swiftmodule file is in ~/mymodules than launch swift with
swift -I ~/mymodules
and then you will be able to import your module
import module name
Should be that easy
In swift,you can't import a typical *.swift file.
For Import Declaration can only be the following syntax:
“
‌ import-declaration → attributesopt import import-kindopt import-path
import-kind → typealias| struct| class| enum| protocol| var| func
‌ import-path → import-path-identifier| import-path-identifier.import-path
‌ import-path-identifier → identifier| operator”
From: Apple Inc. “The Swift Programming Language (Swift 2)”。 iBooks.
which can be described as these formats:
import module
import import kind module.symbol name
import module.submodule
import head.swift is incompatible with import import-kind module.symbol-name
Usually compile the files you want to import as a framework.Then it can be regarded as a module. use -F framework_directory/ to specify 3rd-party frameworks' search path.
Create a file. For example:
// test.swift
import headtest
print("Hello World")
open your terminal
goto the directory where you create the file.
execute command line
swift -F headtest test.swift
And done.
Simply insert the shebang line at the top of your script:
#!/usr/bin/env xcrun swift
You can copy/paste the source code into the repl and execute it.
Not ideal, obviously, but sometimes useful.
Now Swift REPL supports packages. We can do this by the following steps:
In Xcode, select menu File > New > Package. Choose a name for the package, for example MyLibrary.
Copy your codes or .swift files to the Sources/MyLibrary/ directory in your package.
Remember to make your interface public.
In the command line, go to the package directory and run REPL
Like this
cd MyLibrary/
swift run --repl
In the REPL, import your library
Like this
import MyLibrary
Now you can your codes in the REPL.
It looks like it's not possible to import file and get Xcode to use REPL for it using specifications you gave. I think you can still do it creating a proper framework, but it's not exactly what you was looking.

golang using functions of imported subdirectories

I can't use functions of custom subdirectories.
My Code Organziation
I have under "src" a path hierarchy like
a/b
with all my directories and go-Files (it is the "root" of my project). The directories contain no subdirectories and it works fine. So the deepest path is "a/b/c". E.g. I have
a/b/c
and
a/b/d
with some go-files. Import of "a/b/d" and calling a function with "d.DoSomething()" from a file in "a/b/c" works fine.
Problem description
Now I want ot reorganize "a/b/d". I move some files from "a/b/d" to
a/b/d/e
and the rest of the files to
a/b/d/f
If try to import "a/b/d/e" with import-statement
import ( "a/b/d/e" )
from the same file in "/a/b/c" and want to call "e.DoSomething()" (it is the place, where the file with the "DoSomething-function" moved to), I get an error at the line, where I call "e.DoSomething()": "undefined: e".
While searching for a result, I've nowhere seen examples with deeper path hierarchies. Is it generally not possible to use/import subdirectories or what's the problem?
go-version I used: go1.2.2 linux/amd64
Thanks for any advices
Your approach is completely wrong. Go has absolutely no concept of importing files or directories, all you can import in Go are packages. It now happens that the name of a package is it's path relative to GOPATH and you import packages by that name. But the identifier under which an imported package is available in the importing code depends on the package declaration of the package. You cannot simply "move" files between directories as each directory (for the go tool) is a single package without changing the package declaration.
You can have package x under path a/b/c. When you import package x with import ( "a/b/c" ) all the exported stuff from package x is available to you as x.ExportedName.
Please read http://blog.golang.org/organizing-go-code carefully.
Try and do a go build in a/b/d/e first, before trying to build in a/b: that will generate the compiled classes you want to import.