エラー定義
列挙体でエラーを定義します。
enum NetworkError: Error {
case unknown
case invalidResponse
case invalidURL
func description() -> String {
switch self {
case .unknown: return "レスポンスデータの取得失敗です。"
case .invalidResponse: return "不正なレスポンスです。"
case .invalidURL: return "不正なURLです。"
}
}
}
APIクライアント
GithubAPIのAPIクライアントです。
※)今回はクロージャ使用確認のためのコードなのでリクエスト生成のコードはなしです。
import Foundation
class APIClient {
//success: レスポンスデータ(json)取得成功時のクロージャ
//failure: レスポンスデータ(json)取得失敗時のクロージャ
func sendRequest(success: @escaping ([String : Any]) -> (),
failure: @escaping (Error) -> ()) {
//urlの取得(jsonデータ取得)githubAPIを使用
guard let requestUrl = URL(string: "https://api.github.com/search/repositories?q=swift&per_page=1") else {
//不正URLエラー
failure(NetworkError.invalidURL)
return
}
let request = URLRequest(url: requestUrl)
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
//通信エラー
if (error != nil) {
failure(error!)
return
}
//APIからのレスポンス(jsonデータ)
guard let data = data else {
//レスポンスデータの取得失敗のエラー
failure(NetworkError.unknown)
return
}
//jsonデータをパース
guard let jsonOptional = try? JSONSerialization.jsonObject(with: data, options: []),
let json = jsonOptional as? [String: Any] else {
//取得したレスポンスデータ(jsonデータ)が[String: Any]型でなかった時のエラー
failure(NetworkError.invalidResponse)
return
}
success(json)
}
task.resume()
}
}
URLSessionのdataTask(通信)内はスコープが違うようなのでクロージャには@escaping属性を付けておきます。
呼び出し(ViewController)
import UIKit
class ViewController: UIViewController {
var customView:Custom!
override func viewDidLoad() {
super.viewDidLoad()
let api = APIClient()
api.sendRequest(success: {(json) in
//レスポンスデータ(json)取得成功時の処理
print("APIからjsonデータ取得成功")
print(json)
}, failure: {(error) in
//レスポンスデータ(json)取得失敗時の処理
if(error is NetworkError){
let er = error as! NetworkError
print(er.description())
}else {
print("通信エラー")
print(error)
}
})
}
override func viewDidLayoutSubviews() {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
failureクロージャの引数はError型ですが、定義したエラー型(NetworkError)を表示させるためにはNetworkError型のプロパティdescriptionの値を取得する必要があるので、引数errorがNetworkError型である場合はNetworkError型にダウンキャストします。
表示
APIからjsonデータ取得成功
[“incomplete_results”: 0, “total_count”: 138299, “items”: <__NSSingleObjectArrayI 0x600000018000>(
{
“archive_url” = “https://api.github.com/repos/apple/swift/{archive_format}{/ref}”;
archived = 0;
“assignees_url” = “https://api.github.com/repos/apple/swift/assignees{/user}”;
“blobs_url” = “https://api.github.com/repos/apple/swift/git/blobs{/sha}”;
“branches_url” = “https://api.github.com/repos/apple/swift/branches{/branch}”;
“clone_url” = “https://github.com/apple/swift.git”;
“collaborators_url” = “https://api.github.com/repos/apple/swift/collaborators{/collaborator}”;
“comments_url” = “https://api.github.com/repos/apple/swift/comments{/number}”;
“commits_url” = “https://api.github.com/repos/apple/swift/commits{/sha}”;
“compare_url” = “https://api.github.com/repos/apple/swift/compare/{base}…{head}”;
“contents_url” = “https://api.github.com/repos/apple/swift/contents/{+path}”;
“contributors_url” = “https://api.github.com/repos/apple/swift/contributors”;
“created_at” = “2015-10-23T21:15:07Z”;
“default_branch” = master;
“deployments_url” = “https://api.github.com/repos/apple/swift/deployments”;
description = “The Swift Programming Language”;
disabled = 0;
“downloads_url” = “https://api.github.com/repos/apple/swift/downloads”;
“events_url” = “https://api.github.com/repos/apple/swift/events”;
fork = 0;
forks = 7491;
“forks_count” = 7491;
“forks_url” = “https://api.github.com/repos/apple/swift/forks”;
“full_name” = “apple/swift”;
“git_commits_url” = “https://api.github.com/repos/apple/swift/git/commits{/sha}”;
“git_refs_url” = “https://api.github.com/repos/apple/swift/git/refs{/sha}”;
“git_tags_url” = “https://api.github.com/repos/apple/swift/git/tags{/sha}”;
“git_url” = “git://github.com/apple/swift.git”;
“has_downloads” = 1;
“has_issues” = 0;
“has_pages” = 0;
“has_projects” = 0;
“has_wiki” = 0;
homepage = “https://swift.org”;
“hooks_url” = “https://api.github.com/repos/apple/swift/hooks”;
“html_url” = “https://github.com/apple/swift”;
id = 44838949;
“issue_comment_url” = “https://api.github.com/repos/apple/swift/issues/comments{/number}”;
“issue_events_url” = “https://api.github.com/repos/apple/swift/issues/events{/number}”;
“issues_url” = “https://api.github.com/repos/apple/swift/issues{/number}”;
“keys_url” = “https://api.github.com/repos/apple/swift/keys{/key_id}”;
“labels_url” = “https://api.github.com/repos/apple/swift/labels{/name}”;
language = “C++”;
“languages_url” = “https://api.github.com/repos/apple/swift/languages”;
license = {
key = “apache-2.0”;
name = “Apache License 2.0”;
“node_id” = “MDc6TGljZW5zZTI=”;
“spdx_id” = “Apache-2.0”;
url = “https://api.github.com/licenses/apache-2.0”;
};
“merges_url” = “https://api.github.com/repos/apple/swift/merges”;
“milestones_url” = “https://api.github.com/repos/apple/swift/milestones{/number}”;
“mirror_url” = “”;
name = swift;
“node_id” = “MDEwOlJlcG9zaXRvcnk0NDgzODk0OQ==”;
“notifications_url” = “https://api.github.com/repos/apple/swift/notifications{?since,all,participating}”;
“open_issues” = 530;
“open_issues_count” = 530;
owner = {
“avatar_url” = “https://avatars0.githubusercontent.com/u/10639145?v=4”;
“events_url” = “https://api.github.com/users/apple/events{/privacy}”;
“followers_url” = “https://api.github.com/users/apple/followers”;
“following_url” = “https://api.github.com/users/apple/following{/other_user}”;
“gists_url” = “https://api.github.com/users/apple/gists{/gist_id}”;
“gravatar_id” = “”;
“html_url” = “https://github.com/apple”;
id = 10639145;
login = apple;
“node_id” = MDEyOk9yZ2FuaXphdGlvbjEwNjM5MTQ1;
“organizations_url” = “https://api.github.com/users/apple/orgs”;
“received_events_url” = “https://api.github.com/users/apple/received_events”;
“repos_url” = “https://api.github.com/users/apple/repos”;
“site_admin” = 0;
“starred_url” = “https://api.github.com/users/apple/starred{/owner}{/repo}”;
“subscriptions_url” = “https://api.github.com/users/apple/subscriptions”;
type = Organization;
url = “https://api.github.com/users/apple”;
};
private = 0;
“pulls_url” = “https://api.github.com/repos/apple/swift/pulls{/number}”;
“pushed_at” = “2019-04-08T19:29:54Z”;
“releases_url” = “https://api.github.com/repos/apple/swift/releases{/id}”;
score = “156.18651”;
size = 407972;
“ssh_url” = “git@github.com:apple/swift.git”;
“stargazers_count” = 47293;
“stargazers_url” = “https://api.github.com/repos/apple/swift/stargazers”;
“statuses_url” = “https://api.github.com/repos/apple/swift/statuses/{sha}”;
“subscribers_url” = “https://api.github.com/repos/apple/swift/subscribers”;
“subscription_url” = “https://api.github.com/repos/apple/swift/subscription”;
“svn_url” = “https://github.com/apple/swift”;
“tags_url” = “https://api.github.com/repos/apple/swift/tags”;
“teams_url” = “https://api.github.com/repos/apple/swift/teams”;
“trees_url” = “https://api.github.com/repos/apple/swift/git/trees{/sha}”;
“updated_at” = “2019-04-08T19:15:52Z”;
url = “https://api.github.com/repos/apple/swift”;
watchers = 47293;
“watchers_count” = 47293;
}
)
]