This Swift script searches the iTunes Store for a movie by title, provided as a command-line argument, and prints the release date of the first matching result. It uses the iTunes Search API and handles errors gracefully with appropriate exit codes
Click to view script…
#!/usr/bin/env swift
import Foundation
// Define structs to match the iTunes Search API response
struct SearchResponse: Codable {
let resultCount: Int
let results: [Movie]
}
struct Movie: Codable {
let trackName: String
let releaseDate: Date
}
// Check for command-line arguments
if CommandLine.arguments.count < 2 {
print("Usage: \(CommandLine.arguments[0]) <movie title>")
exit(1)
}
// Combine all arguments after the script name into a single movie title
let movieTitle = CommandLine.arguments[1...].joined(separator: " ")
// Construct the API URL
let baseURL = "https://itunes.apple.com/search"
let queryItems = [
URLQueryItem(name: "term", value: movieTitle),
URLQueryItem(name: "media", value: "movie"),
URLQueryItem(name: "entity", value: "movie")
]
var urlComponents = URLComponents(string: baseURL)!
urlComponents.queryItems = queryItems
guard let url = urlComponents.url else {
print("Invalid URL.")
exit(1)
}
// Set up semaphore to handle asynchronous URLSession task
let semaphore = DispatchSemaphore(value: 0)
var exitCode: Int32 = 0 // Explicitly typed as Int32 to match exit() requirement
// Perform the network request
let session = URLSession.shared
let task = session.dataTask(with: url) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
exitCode = 1
} else if let data = data {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601 // Handle ISO 8601 date format from API
do {
let searchResponse = try decoder.decode(SearchResponse.self, from: data)
if searchResponse.resultCount > 0 {
let movie = searchResponse.results[0] // Take the first result
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
let formattedDate = dateFormatter.string(from: movie.releaseDate)
print("Release date of \(movie.trackName): \(formattedDate)")
exitCode = 0
} else {
print("No results found for \"\(movieTitle)\".")
exitCode = 1
}
} catch {
print("Error decoding JSON: \(error)")
exitCode = 1
}
} else {
print("No data received.")
exitCode = 1
}
semaphore.signal() // Signal completion of the network task
}
// Start the task and wait for it to complete
task.resume()
semaphore.wait()
exit(exitCode)