I would like to use the Google Custom Search Engine to store the image URL of Google image search results in an array.
"When I checked the item ""Receive JSON Data"" in the book I had, I found the following code on it."
@IBAction func clickButton (sender:AnyObject) {
let url = NSURL (string: "http://moonmile.net/ios9/persons.json")
let req = NSURLRequest (URL: url!)
let task = NSURLSession.sharedSession().dataTaskWithRequest(req, completionHandler: {
(data, res, err) in
if data!=nil{
dispatch_async(dispatch_get_main_queue(), {
do{
let jeson=try NSJSONSERIALIZATION.JSONObjectWithData(data!,options:NSJSONReadingOptions.MutableContaions)
// Display the first element
let item=(json as!NSArray) [0]
let name = item ["name"] as!String
letage=item["age"] as!Int
let addr=item["address"] as!String
self.text1.text="\(name)\n\(age)\n\(addr)\n"
}catch {
self.text1.text="parse error"
}
})
} else {
dispatch_async(dispatch_get_main_queue(), {
self.text1.text="error"
})
}
})
task.resume()
}
However, it seems to have been a Swift2 compatible book, so it doesn't work well.
Request URL is
https://www.googleapis.com/customsearch/v1?key=????&cx=??&cx=??&q="search word"
in the form of
"I know that ""link"" in the item array of the returning JSON data has the URL of the image I want, but I'm stuck because I can't make something that works with Swift3."
If you have any experience using Google Image Search results images on iOS, please take care of them.
I'm a beginner, but I'd appreciate your advice.
Additional information
@IBAction func clickButton (sender:AnyObject) {
let url = URL (string: "http://moonmile.net/ios9/persons.json")
let req = URLRequest(url:url!)
let task = URLSession.shared.dataTask(with:req, completionHandler:{
(data, res, err) in
if data!=nil{
DispatchQueue.main.asyncrononusly (execute:) {
do{
let jeson=try NSJSONSERIALIZATION.JSONObjectWithData(data!,options:NSJSONReadingOptions.MutableContaions)
// Display the first element
let item=(json as!NSArray) [0]
let name = item ["name"] as!String
letage=item["age"] as!Int
let addr=item["address"] as!String
self.text1.text="\(name)\n\(age)\n\(addr)\n"
}catch {
self.text1.text="parse error"
}
})
} else {
DispatchQueue.main.asynchronously(execute:){
self.text1.text="error"
})
}
})
task.resume()
}
For the time being, I tried to fix it as Xcode told me, but it was clogged with Value of Type DispatchQueue has no member asynchronically (execute:).
Honestly, I have no idea what I'm doing.
Do I have to read all the class descriptions in Apple's official documentation?
Aside from the gray zone :)
let data=str.data(using:.utf8)
let json=try JSONSERIALIZATION.jsonObject(with:data!,options:.mutableContainers)as![String:Any]
let name = json ["Name" ] as!String
Use JSONSERIALIZATION#jsonObject.
First of all, let me ask you this question.
Do I have to read all the class descriptions in Apple's official documentation
If you want to be a programmer enough to convert this level of Swift2 code into Swift3 on your own, you'd better learn to refer directly to the official documentation for stuck areas.If it's okay to be a copier for the rest of your life... there are many ways to live.
So, here's where we are going.
DispatchQueue.main.asyncrononusly(execute:){
value of type 'DispatchQueue' has no member 'asynchronously (execute:)'
The DispatchQueue
type value is asynchronously(execute:)
and no member has it!
"Because of this error, you will have to look into the official reference from the perspective of ""No, that can't be the case, there should be a replacement."""
…
class varmain:DispatchQueue
func getSpecific<T> (key: DispatchSpecificKey<T>)
func setSpecific<T> (key: DispatchSpecificKey<T>, value:T)
func sync(execute:()->Void)
funcasync (execute: DispatchWorkItem)
…
Therefore, if you search every corner of the linked page above, you will not find a method like async(execute:)
, but instead you will find async(execute:)
.(When referring to a method name, the Swift style is to include a parameter label but omit the parameter type name.)
At the moment, you haven't written much about the link anyway, so you have to use your intuition to some extent, but you should know that Swift3 has significantly changed the class name and method name of the existing API.(It's mentioned in Swift3 commentary articles and in Xcode8 Release Notes.)
*Actually, the method name of asynchronously
was changed before Swift3 was 版 version, but it is still a bug to submit it as a candidate.If you have time, please report the bug in Report Bugs.(I think there are already many bug reports, but 8.2 hasn't solved it yet...)
So the next line is
DispatchQueue.main.async(execute:){
If you rewrite to , the compilation passes, but you do not need to write (execute:)
because there is no other async
method that takes a single closure.(It is rare to add (execute:)
in that way.)
DispatchQueue.main.async{
You will make the same corrections in both places.
閉じYou will no longer need closed parentheses ()
), so you will get an error around }
, but you just need to set it to }
.
If you correct the above error, you will see another error in the May rain formula.
let jeson=try NSJSONSERIALIZATION.JSONObjectWithData(data!,options:NSJSONReadingOptions.MutableContaions)
'NSJSONSERIALIZATION' has been renamed to 'JSONSERIALIZATION'
This time it clearly says "renamed" so you don't have to look at the reference.Let's obey honestly.If you use Xcode's Sajeschon, it will look like this.In addition, correct any obvious spelling errors..MutableContainers
->.MutableContainers
let jeson=try JSONSERIALIZATION.jsonObject (with:data!, options:JSONSERIALIZATION.ReadingOptions.mutableContainers)
Note that Swift may omit the type name in some contexts when using the enum type value, but you do not need to specify the mutableContainers
option before that.mutable means rewritable, but this code is just a reference to the contents and has not been rewritten at all.Therefore, options:
itself is not required.(If you look closely, json
is also a mistake in writing json
.)
let json=try JSONSERIALIZATION.jsonObject (with:data!)
After correcting the above, the following error still appears to be present:If you explain everything like ↑, I will lose my mind to read it (at least I will throw it in the middle).…), I'll simplify it a bit, just a comment in the source code, along with the modifications to the recommended writing method.
@IBAction func clickButton (sender:AnyObject) {
let url = URL (string: "http://moonmile.net/ios9/persons.json")!
let req = URLRequest(url:url)
let task = URLSession.shared.dataTask(with:req) {//<- This also uses the syntax of the trailing closure
(data, res, err) in
Iflet data=data{//<-`data` will be used later, so use optional bindings
DispatchQueue.main.async {
do{
// I'll use it as an array of dictionaries later, so I'll cast it at this point.
// Optional binding to prevent apps from crashing when unexpected data arrives
if
let json=try JSONSERIALIZATION.jsonObject(with:data)as?[[String:Any]],
// Display the first element
!json.isEmpty, // If empty, it will crash without the first element, so check it out
caselet item=json[0], // How to write bindings when not optional
let name = item["name"] as ? Check the String, // "name" value before using it. Same as below.
letage=item["age"]as? Int,
let addr=item["address"] as ? String
{
self.text1.text="\(name)\n\(age)\n\(addr)\n"
} else{
self.text1.text="bad json"
}
} catch{
self.text1.text="parse error"
}
}
} else{
DispatchQueue.main.async {
self.text1.text="error"
}
}
}//<- I cut the brackets because I made it into a trailing closure.
task.resume()
}
(Note that you rarely use !
for dangerous forced unwrap or as!
for forced cast.)
It looks like this for now.Actually, we will have to correct the details.Especially if you are using Google Custom Search API,
I think it will need to be corrected in such a way as well.If you think it's going to be a bit complicated, you might want to ask another question.
© 2024 OneMinuteCode. All rights reserved.