【发布时间】:2018-07-06 17:37:52
【问题描述】:
我正在制作一个从牛津词典的 API 中获取单词的拼字游戏。该应用程序提供了预期的单词,但它的失败率比我想要的要高。我的成功率大约是 25% 到 36%;大多数单词都会产生 nil 结果,但这显然是我的错,而不是 API 的错。我想要更高的成功率,因为 API 不是免费的。或者这种命中率是主要 API 的典型特征?
我知道我需要将其更改为 Swift 4 的 Decodable for JSON,但我还没有弄清楚那个。
您能否在我的代码中找到任何会导致完全简单的单词被跳过的内容,例如任何字典中都会出现的单音节单词?在代码的最后,我添加了成功和失败单词的示例控制台日志。
func speakRandomWord() {
//Now that a valid random word is selected, this where I make my API call.
appId = "private"
appKey = "private"
language = "en"
word = randomWord //I get the random word from Lexicontext, Oxford API doesn't support random words yet. I filter out entriest that aren't one word.
regions = "gb"
word_id = word.lowercased()
url = URL(string:"https://odapi.oxforddictionaries.com:443/api/v1/entries/\(language)/\(word_id)/regions=\(regions)")!
var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(appId, forHTTPHeaderField: "app_id")
request.addValue(appKey, forHTTPHeaderField: "app_key")
let session = URLSession.shared
print ("URLSession began...")
dataAttempted += 1
_ = session.dataTask(with: request, completionHandler: { data, response, error in
if let httpResponse = response as? HTTPURLResponse {
print("statusCode: \(httpResponse.statusCode)")
if httpResponse.statusCode != 200 {
print ("URLSession failed, trying again...")
self.urlSessionFailed += 1
self.selectRandomWord()
self.speakRandomWord()
}
}
DispatchQueue.main.async { [unowned self] in
self.activitySpinner.stopAnimating()
self.activitySpinner.isHidden = true
self.theUserInput.becomeFirstResponder()
self.repeatButton.isEnabled = true
self.defineButton.isEnabled = true
}
if let response = response,
let data = data,
let jsonData = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
{
if
let dictionary = jsonData as? [String: Any],
let results = dictionary["results"] as? [[String: Any]],
!results.isEmpty, case var result = results[0],
let lexicalEntries = result["lexicalEntries"] as? [[String: Any]],
!lexicalEntries.isEmpty, case var lexicalEntry = lexicalEntries[0],
let derivatives = lexicalEntry["derivatives"] as? [[String:Any]],
!derivatives.isEmpty, case var derivative = derivatives[0],
let pronunciations = lexicalEntry["pronunciations"] as? [[String: Any]],
!pronunciations.isEmpty, case var pronunciation = pronunciations[0],
let entries = lexicalEntry["entries"] as? [[String:Any]],
!entries.isEmpty, case var entry = entries[0],
let senses = entry["senses"] as? [[String:Any]],
!senses.isEmpty, case var sense = senses[0],
let examples = sense["examples"] as? [[String:Any]],
!examples.isEmpty, case var example = examples[0]
//Now I pick out details from the JSON like audio, sample sentence, etc.
{
if let theText = example.removeValue(forKey:"text") {
self.theText = String(describing:theText)
print ("The value is \(self.theText)")
}
if let meaning = sense.removeValue(forKey:"short_definitions") {
self.newMeaning = String(describing:meaning)
print ("The short meaning is \(self.meaning)")
}
if let origin = entry.removeValue(forKey:"etymologies") {
self.newEtymology = String(describing:origin)
self.decoded2 = String(self.newEtymology.characters.filter({!"U0123456789".contains(String($0))}))
// print ("The etymology is \(self.decoded2)")
}
if let audioPath = pronunciation.removeValue(forKey:"audioFile") {
print ("MP3 audio file for \(self.word) exists")
print (audioPath)
self.audioPaths.append(audioPath as! String)
self.dataIsValid += 1
self.successfulWords.append(self.word)
self.path = String(describing:audioPath)
self.repeatPath = self.path
print (self.path)
if let url = URL.init(string: self.path) {
self.player = AVPlayer.init(url: url)
self.player.play()
}
}
else {
print ("No audio data for \(self.word)!")
self.dataFailed += 1
self.audioFailed.append(self.word)
self.selectRandomWord()
}
}
else {
print ("\(self.randomWord) failed, reason unknown!")
self.dataFailed += 1
self.failedOtherReason.append(self.word)
self.selectRandomWord()
}
}
}).resume()
}
// Console results:
//URL Session failures: 5
//API attempts: 41.0
//API successes: 15.0
//API failures: 21.0
//Successful Oxford API hit percentage: 36.5853658536585
//These 15 words succeeded: ["denunciation", "strategic", "strategic", "detract", "opaline", "opaline", "jurist", "exit", "throaty", "mother", "mother", "regroup", "early", "managerial", "recalcitrant"]
//These 0 words had no audio: []
//These words 21 words failed for an unknown reason: ["overlook", "lignin", "mandate", "evident", "anagrammatize", "avoirdupois", "extraterrestrial", "opaline", "cauterization", "malted", "clear", "snuggle", "fresno", "jurist", "streamline", "nonconforming", "trochee", "adventitia", "rudiment", "sculpturesque", "bicycle"]
【问题讨论】:
-
不相关但
var result = results.first { ...比!results.isEmpty, case var result = results[0] { ...高效得多 -
尝试使用 SwiftyJSON - 更简单