Skip to content

Commit

Permalink
Modify completion as Result type
Browse files Browse the repository at this point in the history
  • Loading branch information
cozzin committed Aug 10, 2019
1 parent f81f0aa commit a14b313
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 74 deletions.
2 changes: 1 addition & 1 deletion Cartfile.private
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "AliSoftware/OHHTTPStubs" "6.0.0"
github "AliSoftware/OHHTTPStubs" "8.0.0"
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "AliSoftware/OHHTTPStubs" "6.0.0"
github "AliSoftware/OHHTTPStubs" "8.0.0"
8 changes: 4 additions & 4 deletions OpenGraph.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TVOS_DEPLOYMENT_TARGET = 9.0;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
Expand Down Expand Up @@ -435,7 +435,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TVOS_DEPLOYMENT_TARGET = 9.0;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
Expand All @@ -456,7 +456,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "net.cloud-dj.OpenGraphTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand All @@ -474,7 +474,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.cloud-dj.OpenGraphTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand Down
61 changes: 23 additions & 38 deletions OpenGraph/OpenGraph.swift
Original file line number Diff line number Diff line change
@@ -1,54 +1,39 @@
import Foundation

public struct OpenGraph {
public let source: [OpenGraphMetadata: String]

public static func fetch(url: URL, completion: @escaping (OpenGraph?, Error?) -> Void) {
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)
let task = session.dataTask(with: url, completionHandler: { (data, response, error) in
handleFetchResult(data: data, response: response, error: error, callback: completion)
})
task.resume()
}
public let source: [OpenGraphMetadata: String]

public static func fetch(url: URL, headers: [String:String], completion: @escaping (OpenGraph?, Error?) -> Void) {
public static func fetch(url: URL, headers: [String: String]? = nil, completion: @escaping (Result<OpenGraph, Error>) -> Void) {
var mutableURLRequest = URLRequest(url: url)
for hkey in headers.keys {
let value:String! = headers[hkey]
if value != nil {
mutableURLRequest.setValue(value, forHTTPHeaderField: hkey)
}
headers?.compactMapValues { $0 }.forEach {
mutableURLRequest.setValue($1, forHTTPHeaderField: $0)
}

let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)
let task = session.dataTask(with: mutableURLRequest, completionHandler: { (data, response, error) in
handleFetchResult(data: data, response: response, error: error, callback: completion)
})
let task = session.dataTask(with: mutableURLRequest, completionHandler: { data, response, error in
if let error = error {
completion(.failure(error))
} else {
handleFetchResult(data: data, response: response, completion: completion)
}
})
task.resume()
}

private static func handleFetchResult(data: Data?, response: URLResponse?, error: Error?, callback: @escaping (OpenGraph?, Error?) -> Void){
switch (data, response, error) {
case (_, _, let error?):
callback(nil, error)
break
case (let data?, let response as HTTPURLResponse, _):
if !(200..<300).contains(response.statusCode) {
callback(nil, OpenGraphResponseError.unexpectedStatusCode(response.statusCode))
} else {
guard let htmlString = String(data: data, encoding: String.Encoding.utf8) else {
callback(nil, OpenGraphParseError.encodingError)
return
}

let og = OpenGraph(htmlString: htmlString)
callback(og, error)
private static func handleFetchResult(data: Data?, response: URLResponse?, completion: @escaping (Result<OpenGraph, Error>) -> Void) {
guard let data = data, let response = response as? HTTPURLResponse else {
return
}
if !(200..<300).contains(response.statusCode) {
completion(.failure(OpenGraphResponseError.unexpectedStatusCode(response.statusCode)))
} else {
guard let htmlString = String(data: data, encoding: String.Encoding.utf8) else {
completion(.failure(OpenGraphParseError.encodingError))
return
}
break
default:
break
let og = OpenGraph(htmlString: htmlString)
completion(.success(og))
}
}

Expand Down
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,39 @@
OpenGraph is a Swift wrapper for the OGP ([Open Graph protocol](http://ogp.me/)).
You can fetch OpenGraph,then you can access the attributes with subscript and the key provided by enum type.
```swift
OpenGraph.fetch(url) { og, error in
print(og?[.title]) // => og:title of the web site
print(og?[.type]) // => og:type of the web site
print(og?[.image]) // => og:image of the web site
print(og?[.url]) // => og:url of the web site
OpenGraph.fetch(url: url) { result in
switch result {
case .success(let og):
print(og[.title]) // => og:title of the web site
print(og[.type]) // => og:type of the web site
print(og[.image]) // => og:image of the web site
print(og[.url]) // => og:url of the web site
case .failure(let error):
print(error)
}
}
```

If you want to use Rx interface, use an extension below.
```swift
extension OpenGraph {
static func rx_fetch(url: URL?) -> Observable<OpenGraph?> {
extension Reactive where Base: OpenGraph {
static func fetch(url: URL?) -> Observable<OpenGraph> {
return Observable.create { observer in
guard let url = url else {
observer.onCompleted()
return Disposables.create()
}

OpenGraph.fetch(url: url) { og, err in
if let og = og {

OpenGraph.fetch(url: url) { result in
switch result {
case .success(let og):
observer.onNext(og)
case .failure(let error):
observer.onError(error)
}
if let err = err {
observer.onError(err)
}

observer.onCompleted()
}

return Disposables.create()
}
}
Expand Down
40 changes: 25 additions & 15 deletions Tests/OpenGraphTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ class OpenGraphTests: XCTestCase {
var og: OpenGraph!
var error: Error?
let headers = ["User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"]
OpenGraph.fetch(url: url, headers: headers) { (_og, _error) in
og = _og
error = _error
OpenGraph.fetch(url: url, headers: headers) { result in
switch result {
case .success(let _og): og = _og
case .failure(let _error): error = _error
}
responseArrived.fulfill()
}

Expand All @@ -57,9 +59,11 @@ class OpenGraphTests: XCTestCase {
let url = URL(string: "https://www.example.com")!
var og: OpenGraph!
var error: Error?
OpenGraph.fetch(url: url) { _og, _error in
og = _og
error = _error
OpenGraph.fetch(url: url) { result in
switch result {
case .success(let _og): og = _og
case .failure(let _error): error = _error
}
responseArrived.fulfill()
}

Expand All @@ -82,9 +86,11 @@ class OpenGraphTests: XCTestCase {
let url = URL(string: "https://www.example.com")!
var og: OpenGraph!
var error: Error?
OpenGraph.fetch(url: url) { _og, _error in
og = _og
error = _error
OpenGraph.fetch(url: url) { result in
switch result {
case .success(let _og): og = _og
case .failure(let _error): error = _error
}
responseArrived.fulfill()
}

Expand All @@ -110,9 +116,11 @@ class OpenGraphTests: XCTestCase {
let url = URL(string: "https://www.example.com")!
var og: OpenGraph?
var error: Error?
OpenGraph.fetch(url: url) { _og, _error in
og = _og
error = _error
OpenGraph.fetch(url: url) { result in
switch result {
case .success(let _og): og = _og
case .failure(let _error): error = _error
}
responseArrived.fulfill()
}

Expand Down Expand Up @@ -144,9 +152,11 @@ class OpenGraphTests: XCTestCase {
let url = URL(string: "https://www.example.com")!
var og: OpenGraph?
var error: Error?
OpenGraph.fetch(url: url) { _og, _error in
og = _og
error = _error
OpenGraph.fetch(url: url) { result in
switch result {
case .success(let _og): og = _og
case .failure(let _error): error = _error
}
responseArrived.fulfill()
}

Expand Down

0 comments on commit a14b313

Please sign in to comment.