-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dfaa6bb
commit 7ef4944
Showing
7 changed files
with
242 additions
and
17 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// HtmlRequest.swift | ||
// URLEmbeddedView | ||
// | ||
// Created by marty-suzuki on 2017/10/08. | ||
// Copyright © 2017年 marty-suzuki. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import Kanna | ||
|
||
struct HtmlRequest: OGRequest { | ||
let url: URL | ||
|
||
init(url: URL) { | ||
self.url = url | ||
} | ||
|
||
static func response(data: Data) throws -> OpenGraph.HTML { | ||
guard | ||
let html = Kanna.HTML(html: data, encoding: String.Encoding.utf8), | ||
let header = html.head | ||
else { | ||
throw OGSession.Error.castFaild | ||
} | ||
return try OpenGraph.HTML(element: header) ?? { throw OGSession.Error.htmlDecodeFaild }() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// OGRequest.swift | ||
// URLEmbeddedView | ||
// | ||
// Created by marty-suzuki on 2017/10/08. | ||
// Copyright © 2017年 marty-suzuki. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
private let userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Safari/601.1.42" | ||
|
||
protocol OGRequest { | ||
associatedtype Response | ||
var url: URL { get } | ||
var urlRequest: URLRequest { get } | ||
static func response(data: Data) throws -> Response | ||
} | ||
|
||
extension OGRequest { | ||
var urlRequest: URLRequest { | ||
var request = URLRequest(url: url) | ||
request.setValue(userAgent, forHTTPHeaderField: "User-Agent") | ||
request.timeoutInterval = 5 | ||
return request | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// | ||
// File.swift | ||
// URLEmbeddedView | ||
// | ||
// Created by marty-suzuki on 2017/10/08. | ||
// | ||
|
||
import Foundation | ||
|
||
final class OGSession { | ||
struct Task { | ||
let uuidString: String | ||
let task: URLSessionDataTask | ||
} | ||
|
||
enum Error: Swift.Error { | ||
case castFaild | ||
case jsonDecodeFaild | ||
case htmlDecodeFaild | ||
case other(Swift.Error) | ||
} | ||
|
||
private let session: URLSession | ||
|
||
init(configuration: URLSessionConfiguration = .default) { | ||
configuration.timeoutIntervalForRequest = 30 | ||
configuration.timeoutIntervalForResource = 60 | ||
self.session = URLSession(configuration: configuration) | ||
} | ||
|
||
func send<T: OGRequest>(_ request: T, completion: @escaping (T.Response?, Error?) -> Void) -> Task { | ||
let task = session.dataTask(with: request.urlRequest) { data, response, error in | ||
guard let data = data else { | ||
let e = error.map { Error.other($0) } | ||
completion(nil, e) | ||
return | ||
} | ||
do { | ||
let response = try T.response(data: data) | ||
completion(response, nil) | ||
} catch let e as Error { | ||
completion(nil, e) | ||
} catch let e { | ||
completion(nil, .other(e)) | ||
} | ||
} | ||
return Task(uuidString: UUID().uuidString, task: task) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// | ||
// OpenGraph.swift | ||
// URLEmbeddedView | ||
// | ||
// Created by marty-suzuki on 2017/10/08. | ||
// Copyright © 2017年 marty-suzuki. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import Kanna | ||
|
||
/// name space | ||
enum OpenGraph {} | ||
|
||
extension OpenGraph { | ||
struct HTML { | ||
private enum Const { | ||
static let metaTagKey = "meta" | ||
static let propertyKey = "property" | ||
static let contentKey = "content" | ||
static let propertyPrefix = "og:" | ||
} | ||
|
||
struct Metadata { | ||
let property: String | ||
let content: String | ||
} | ||
let metaList: [Metadata] | ||
|
||
init?(element: XMLElement) { | ||
let metaTags = element.xpath(Const.metaTagKey) | ||
let metaList = metaTags.enumerated().flatMap { _, metaTag -> Metadata? in | ||
guard | ||
let property = metaTag[Const.propertyKey], | ||
let content = metaTag[Const.contentKey], | ||
property.hasPrefix(Const.propertyPrefix) | ||
else { return nil } | ||
return Metadata(property: property, content: content) | ||
} | ||
if metaList.isEmpty { return nil } | ||
self.metaList = metaList | ||
} | ||
} | ||
} | ||
|
||
extension OpenGraph { | ||
struct Youtube { | ||
let title: String | ||
let type: String | ||
let providerName: String | ||
let thumbnailUrl: String | ||
|
||
init?(json: [AnyHashable : Any]) { | ||
guard let title = json["title"] as? String else { return nil } | ||
self.title = title | ||
|
||
guard let type = json["type"] as? String else { return nil } | ||
self.type = type | ||
|
||
guard let providerName = json["provider_name"] as? String else { return nil } | ||
self.providerName = providerName | ||
|
||
guard let thumbnailUrl = json["thumbnail_url"] as? String else { return nil } | ||
self.thumbnailUrl = thumbnailUrl | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// YoutubeEmbedRequest.swift | ||
// URLEmbeddedView | ||
// | ||
// Created by marty-suzuki on 2017/10/08. | ||
// Copyright © 2017年 marty-suzuki. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
struct YoutubeEmbedRequest: OGRequest { | ||
let url: URL | ||
|
||
init?(url: URL) { | ||
guard | ||
let escapedString = url.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), | ||
let url = URL(string: "https://www.youtube.com/oembed?url=\(escapedString)") | ||
else { return nil } | ||
self.url = url | ||
} | ||
|
||
static func response(data: Data) throws -> OpenGraph.Youtube { | ||
let rawJson = try JSONSerialization.jsonObject(with: data, options: []) | ||
let json = try (rawJson as? [AnyHashable : Any]) ?? { throw OGSession.Error.castFaild }() | ||
return try OpenGraph.Youtube(json: json) ?? { throw OGSession.Error.jsonDecodeFaild }() | ||
} | ||
} |