Skip to content

How to resolve 'cannot find URL in scope' when accessing URL with XCode Playground

1. Purpose

In this post, I will demonstrate how to resolve the following exception when using Xcode Playground to test a Swift program that accesses 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, Xcode complains that:

Terminal window
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:

Playground.swift
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

3.2.1 About Swift import

The URL and URLSession classes are defined in other modules like Foundation, so we should import them before using them.

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 search for 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 waits for the URL to be accessed and processes the response, as shown below:

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:

Playground.swift
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 resolve the ‘cannot find class in scope’ error in Xcode Playground. The key steps are to ensure that you have imported the necessary modules (such as Foundation and PlaygroundSupport) and enabled indefinite execution for asynchronous tasks. By following these steps, you can successfully access URLs and handle responses in your Swift code within Xcode Playground.

Final Words + More Resources

My intention with this article was to help others who might be considering solving such a problem. So I hope that’s been the case here. If you still have any questions, don’t hesitate to ask me by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!