mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-21 00:22:12 +00:00
New fetching details method
- Second method to fetch details with async js code
This commit is contained in:
parent
c643e02b8e
commit
d3fc29d8ed
2 changed files with 170 additions and 7 deletions
|
|
@ -31,6 +31,7 @@ class JSController: ObservableObject {
|
||||||
}
|
}
|
||||||
let task = URLSession.shared.dataTask(with: url) { data, _, error in
|
let task = URLSession.shared.dataTask(with: url) { data, _, error in
|
||||||
if let error = error {
|
if let error = error {
|
||||||
|
print(url)
|
||||||
print("Network error in fetchNativeFunction: \(error.localizedDescription)")
|
print("Network error in fetchNativeFunction: \(error.localizedDescription)")
|
||||||
reject.call(withArguments: [error.localizedDescription])
|
reject.call(withArguments: [error.localizedDescription])
|
||||||
return
|
return
|
||||||
|
|
@ -271,4 +272,153 @@ class JSController: ObservableObject {
|
||||||
promise.invokeMethod("then", withArguments: [thenFunction])
|
promise.invokeMethod("then", withArguments: [thenFunction])
|
||||||
promise.invokeMethod("catch", withArguments: [catchFunction])
|
promise.invokeMethod("catch", withArguments: [catchFunction])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use Javascript to fetch details
|
||||||
|
func fetchDetailsJS(url: String, completion: @escaping ([MediaItem], [EpisodeLink]) -> Void) {
|
||||||
|
guard let url = URL(string: url) else {
|
||||||
|
completion([], [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let exception = context.exception {
|
||||||
|
print("JavaScript exception: \(exception)")
|
||||||
|
completion([], [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let extractDetailsFunction = context.objectForKeyedSubscript("extractDetails") else {
|
||||||
|
print("No JavaScript function extractDetails found")
|
||||||
|
completion([], [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let extractEpisodesFunction = context.objectForKeyedSubscript("extractEpisodes") else {
|
||||||
|
print("No JavaScript function extractEpisodes found")
|
||||||
|
completion([], [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultItems: [MediaItem] = []
|
||||||
|
var episodeLinks: [EpisodeLink] = []
|
||||||
|
|
||||||
|
// Call the JavaScript function, passing in the parameter
|
||||||
|
let promiseValueDetails = extractDetailsFunction.call(withArguments: [url.absoluteString])
|
||||||
|
guard let promiseDetails = promiseValueDetails else {
|
||||||
|
print("extractDetails did not return a Promise")
|
||||||
|
completion([], [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles successful promise resolution.
|
||||||
|
let thenBlockDetails: @convention(block) (JSValue) -> Void = { result in
|
||||||
|
|
||||||
|
if let jsonOfDetails = result.toString(),
|
||||||
|
let dataDetails = jsonOfDetails.data(using: .utf8) {
|
||||||
|
do {
|
||||||
|
if let array = try JSONSerialization.jsonObject(with: dataDetails, options: []) as? [[String: Any]] {
|
||||||
|
resultItems = array.map { item -> MediaItem in
|
||||||
|
let description = item["description"] as? String ?? ""
|
||||||
|
let aliases = item["aliases"] as? String ?? ""
|
||||||
|
let airdate = item["airdate"] as? String ?? ""
|
||||||
|
return MediaItem(description: description, aliases: aliases, airdate: airdate)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("Failed to parse JSON of extractDetails")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("JSON parsing error of extract details: \(error)")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("Result is not a string of extractDetails")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles promise rejection.
|
||||||
|
let catchBlockDetails: @convention(block) (JSValue) -> Void = { error in
|
||||||
|
print("Promise rejected of extractDetails: \(String(describing: error.toString()))")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the Swift blocks into JSValue functions
|
||||||
|
let thenFunctionDetails = JSValue(object: thenBlockDetails, in: context)
|
||||||
|
let catchFunctionDetails = JSValue(object: catchBlockDetails, in: context)
|
||||||
|
|
||||||
|
// Attach the 'then' and 'catch' callbacks to the Promise
|
||||||
|
promiseDetails.invokeMethod("then", withArguments: [thenFunctionDetails])
|
||||||
|
promiseDetails.invokeMethod("catch", withArguments: [catchFunctionDetails])
|
||||||
|
|
||||||
|
|
||||||
|
// Call the JavaScript function, passing in the parameter
|
||||||
|
let promiseValueEpisodes = extractEpisodesFunction.call(withArguments: [url.absoluteString])
|
||||||
|
guard let promiseEpisodes = promiseValueEpisodes else {
|
||||||
|
print("extractEpisodes did not return a Promise")
|
||||||
|
completion([], [])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles successful promise resolution.
|
||||||
|
let thenBlockEpisodes: @convention(block) (JSValue) -> Void = { result in
|
||||||
|
|
||||||
|
if let jsonOfEpisodes = result.toString(),
|
||||||
|
let dataEpisodes = jsonOfEpisodes.data(using: .utf8) {
|
||||||
|
do {
|
||||||
|
if let array = try JSONSerialization.jsonObject(with: dataEpisodes, options: []) as? [[String: Any]] {
|
||||||
|
episodeLinks = array.map { item -> EpisodeLink in
|
||||||
|
let number = item["number"] as? Int ?? 0
|
||||||
|
let href = item["href"] as? String ?? ""
|
||||||
|
return EpisodeLink(number: number, href: href)
|
||||||
|
}
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion(resultItems, episodeLinks)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
print("Failed to parse JSON of extractEpisodes")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("JSON parsing error of extractEpisodes: \(error)")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("Result is not a string of extractEpisodes")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles promise rejection.
|
||||||
|
let catchBlockEpisodes: @convention(block) (JSValue) -> Void = { error in
|
||||||
|
print("Promise rejected of extractEpisodes: \(String(describing: error.toString()))")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion([], [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the Swift blocks into JSValue functions
|
||||||
|
let thenFunctionEpisodes = JSValue(object: thenBlockEpisodes, in: context)
|
||||||
|
let catchFunctionEpisodes = JSValue(object: catchBlockEpisodes, in: context)
|
||||||
|
|
||||||
|
// Attach the 'then' and 'catch' callbacks to the Promise
|
||||||
|
promiseEpisodes.invokeMethod("then", withArguments: [thenFunctionEpisodes])
|
||||||
|
promiseEpisodes.invokeMethod("catch", withArguments: [catchFunctionEpisodes])
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,14 +198,27 @@ struct MediaInfoView: View {
|
||||||
do {
|
do {
|
||||||
let jsContent = try moduleManager.getModuleContent(module)
|
let jsContent = try moduleManager.getModuleContent(module)
|
||||||
jsController.loadScript(jsContent)
|
jsController.loadScript(jsContent)
|
||||||
jsController.fetchDetails(url: href) { items, episodes in
|
if(module.metadata.asyncJS == false || module.metadata.asyncJS == nil) {
|
||||||
if let item = items.first {
|
jsController.fetchDetails(url: href) { items, episodes in
|
||||||
self.synopsis = item.description
|
if let item = items.first {
|
||||||
self.aliases = item.aliases
|
self.synopsis = item.description
|
||||||
self.airdate = item.airdate
|
self.aliases = item.aliases
|
||||||
|
self.airdate = item.airdate
|
||||||
|
}
|
||||||
|
self.episodeLinks = episodes
|
||||||
|
self.isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jsController.fetchDetailsJS(url: href) { items, episodes in
|
||||||
|
if let item = items.first {
|
||||||
|
self.synopsis = item.description
|
||||||
|
self.aliases = item.aliases
|
||||||
|
self.airdate = item.airdate
|
||||||
|
}
|
||||||
|
self.episodeLinks = episodes
|
||||||
|
self.isLoading = false
|
||||||
}
|
}
|
||||||
self.episodeLinks = episodes
|
|
||||||
self.isLoading = false
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
print("Error loading module: \(error)")
|
print("Error loading module: \(error)")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue