others-how to solve 'cannot find URL in scope' when accessing URL with XCode Playground ?

1. Purpose

In this post, I would demo how to solve the below exception when using xcode playground to test swift program that access a url.

cannot find URL in scope

cannot find URLSession in scope

2. Environment

  • Mac OS
  • Xcode
  • Swift

3. The solution

3.1 The code that caused the problem

let url = URL(string: "http://www.stackoverflow.com")!

let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
    guard let data = data else { return }
    print(String(data: data, encoding: .utf8)!)
}

task.resume()

When compiling, the xcode complains that:

cannot find URL in scope

cannot find URLSession in scope

3.2 The solution

Here is the solution, we should add some imports to the header of the code:

import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
3.2.1 About swift import

The URL and URLSession class are defined in other modules like Foundation, we should import it before we use it.

An import declaration lets you access symbols that are declared outside the current file. The basic form imports the entire module; it consists of the import keyword followed by a module name:

import module

Providing more detail limits which symbols are imported—you can specify a specific submodule or a specific declaration within a module or submodule.

But how can I know which module the URL class belongs to ? We can just search this in Google:

swift class URL

Then we should see the link that points to apple developer documents, e.g. https://developer.apple.com/documentation/foundation/url

image-20210415200041850

3.2.2 About the needsIndefiniteExecution

We defined a variable needsIndefiniteExecution:

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

By default, when all top-level code is executed, the execution is terminated. When working with asynchronous code, enable indefinite execution to allow execution to continue after the end of the playground’s top-level code is reached. This, in turn, gives threads and callbacks time to execute.

We set this flag because we have an asynchronous process that would wait for the URL to be accessed and process the response, just as follows:

let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
    guard let data = data else { return }
    print(String(data: data, encoding: .utf8)!)
}

In the above code, we passed a closure function to the dataTask function to process the URL response when the connection succeeded.

3.3 The total lines of code

Here is the whole code of our example:

import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

let url = URL(string: "http://www.stackoverflow.com")!

let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
    guard let data = data else { return }
    print(String(data: data, encoding: .utf8)!)
}

task.resume()

Now it works!

4. Summary

In this post, I demonstrated how to solve the ‘cannot find class in scope’ error in xcode playground, be sure to check you have imported the classes you are using .