Cannot call value of non function type '[String:AnyObject]' - swift3

I'm facing the issue in Swift 3
I have following piece of code:
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
if let datasFromJson = json["blog"] as? [[String:AnyObject]] {
for dataFromJson in datasFromJson{
if let title = dataFromJson("title")! as? String {
article.author = author
}
self.articles?.append(article)
}
}
I get this error when I try to cast title as string

Typo (brackets, not parentheses):
dataFromJson["title"] as? String // no exclamation mark after the closing bracket
Notes:
.mutableContainers is useless in Swift.
In Swift 3 JSON dictionary is [String:Any]
Is title used at all? Or is it another typo title vs. author?

Related

Swift2 to Swift3 error - Cannot assign value of type 'NSDictionary?' to type 'AddressModel'

Moving an app from Swift2 to Swift3 and I've hit an error that I've been unable to fix after trying several different suggestions.
lazy var address: AddressModel? = {
[unowned self] in
var dict = self.getpayloadDict()
var model: AddressModel
model = dict
return model
}()
model = dict throws Cannot assign value of type 'NSDictionary?' to type 'AddressModel'
The AddressModel . . .
class AddressModel: Deserializable {
var City: String?
var State: String?
var PostalCode: String?
required init(data: [String: AnyObject]) {
City = data["City"] as! String?
State = data["State"] as! String?
PostalCode = data["PostalCode"] as! String?
}
}
Any help appreciated.
The error is supposed to occur also in Swift 2. It's pretty clear: getpayloadDict() returns a dictionary which doesn't match AddressModel.
You might create an AddressModel instance from the dictionary
lazy var address: AddressModel? = { // this closure does not cause a retain cycle
let dict = self.getpayloadDict()
return AddressModel(data: dict)
}()
Side note:
as! String? (force unwrap an optional to an optional) is horrible syntax. Use regular conditional downcast as? String. And please conform to the naming convention that variable names start with a lowercase letter.

Getting nil response while passing string to another view controller - Swift3

In FirstViewController i'm fetching the response from JSON and want to pass that fetched response to another view controller.Below is the code which i have used so far for parsing and passing the response.
FirstViewController
var fn:String! //globally declared variable
code i have tried for parsing in FirstViewController
do {
let detailsDictionary:NSDictionary = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! Dictionary<String, AnyObject> as NSDictionary
print(detailsDictionary)
let details = detailsDictionary["Data"] as! [[String:AnyObject]]
print(details)
for dtl in details
{
self.fn = dtl["Father_Name"] as? String ?? "NA"
print(self.fn) //here i'm getting the exact value from JSON
}
}
}
SecondViewController
In SecondViewController there is a Label called profile_name and want to set that parsed string(fn) as Label's text. for that i declared another variable as global.
var pname:String!
below is the code i have used to fetch the value from FirstViewController.
viewDidLoad()
{
let othervc = FirstViewController()
self.pname = othervc.fn
self.profile_name.text = self.pname
}
Problem : I tried my best efforts to get the desired output but i'm getting nil response.
Please Help.
In Second ViewController
let strName:String!
In First ViewController
let strOne = "This is for testing"
let objstory = self.storyboard?.instantiateViewController(withIdentifier: "yout Secoond ViewController Storybord ID") as! YourSecondViewControllerName
objstory.strNam = strOne
self.navigationController?.pushViewController(objstory, animated: true)
Your updated code just won't work.
let othervc = FirstViewController()
creates a new instance of FirstViewController (not the one that got the JSON).
You should be handling it something like this:
In FirstViewController
let fn = dtl["Father_Name"] as? String ?? "NA"
let svc = SecondViewController() // Or maybe instantiate from Storyboard, or maybe you already have a reference to it
svc.pname = fn
present(svc, animated: true, completion: nil)
Then in SecondViewController
override func viewDidLoad() {
super.viewDidLoad()
profile_name.text = pname
}
I'd suggest you take some time out and re-read Apple's View Controller programming guide.
Original Answer
The problem you have here…
vcvalue.profile_name.text = fn
is that profile_name is nil as the view for the view controller hasn't been loaded at this point.
You should handle this by creating a property in LeftSideMenuViewController
var name: String?
Then set
vcvalue.name = fn
And then in LeftSideMenuViewController
override func viewDidLoad() {
super.viewDidLoad()
profile_name.text = name
}
Also, some basic tips…
Don't force unwrap (!) apart from IBOutlets. You may have to write a bit more code, but you will reduce crashes.
Make #IBOutlets private - this will prevent you accidentally assigning to them as you are now
If you're overriding any viewWill/DidDis/Appear methods, you must call super at some point.
You need to re-read the section on switch/case
So this…
let a = indexPath.row
switch(a)
{
case 0 :
if(a == 0)
{
return 45
}
break
etc
could just be…
switch indexPath.row {
case 0...4:
return 45
case 5:
return 50
default:
break
}

How to get window id from the title by swift3

How can I get a CGWindowID from the title of it?
I thought I can get list of titles by this code
let options = CGWindowListOption(arrayLiteral: CGWindowListOption.excludeDesktopElements, CGWindowListOption.optionOnScreenOnly)
let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
let infoList = windowListInfo as NSArray? as? [[String: AnyObject]]
https://stackoverflow.com/a/31367468/1536527
But it seems there is no info for title of the windows.
How can I get CGWindowID or any info to specify a window by title?
Actually the code snippet you posted seems to work for me. All I did was to iterate over the dictionary and find the window info for a given window title.
Here is the code:
func getWindowInfo(pname: String) -> Dictionary<String, AnyObject> {
var answer = Dictionary<String, AnyObject>()
let options = CGWindowListOption(arrayLiteral: CGWindowListOption.optionOnScreenOnly)
let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
let infoList = windowListInfo as NSArray? as? [[String: AnyObject]]
infoList?.forEach{eachDict in
eachDict.keys.forEach{ eachKey in
if (eachKey == "kCGWindowName" && eachDict[eachKey] != nil ){
let name = eachDict[eachKey] as? String ?? ""
print (name)
if ( name == pname){
print("******** Found **********")
answer = eachDict as! Dictionary<String, AnyObject>
}
}
print(eachKey , "-->" , eachDict[eachKey])
}
}
return answer
}
With the above function, I am able to get a window's details, including name for example.
I hope it works for you too.

Cannot subscript a value of type [[String:Any]] with an index of type 'String' - Swift 3

I am converting my code in Swift 3 and I am getting this error on the line:
let dicArray = serviceProvicedListArray?.objectEnumerator().allObjects as? [[String:Any]]
let count = dicArray.map({ Int($0["lstActType"] as? String ?? "0")! }).first!
Exception: Cannot subscript a value of type [[String:Any]] with an index of type 'String'
Please let me know where I am going wrong and let me know how I resolve the same.
Also getting error on this line:
let user_id=String(((data as AnyObject).value(forKey: "UserLoginResult") as AnyObject).value(forKey: "UserID") as! Int)
Exception: Optional chain has no effect expression already produced Any?
Does not understand where I am going wrong
Error 3:
if(!((self.serviceProvided!.value(forKey: "Weekly")! as AnyObject).isKind(of: NSNull.self))){
let resultObject = self.serviceProvided!.value(forKey: "Weekly") as! NSDictionary
self.serviceProvicedListArray!.add(resultObject)
let resultObjectItems = self.serviceProvicedListArray!.value(forKey: "lstActType")
//print(resultObjectItems[0].count)
for i in 0..<resultObjectItems[0].count {
//for(var i=0; i<resultObjectItems[0].count; i += 1){
//let resultObjectItem = resultObjectItems[0][i] as! NSDictionary
let resultObjectItem = resultObjectItems[0][i] as AnyObject
self.serviceProvicedList!.add(resultObjectItem)
}
//print(self.serviceProvicedList)
self.serviceProvidedTableView.reloadData()
}
Thanks in advance.
Your dicArray is optional so you need to wrap it with ?(Optional) or !(force) and then call map on it.
let dicArray = serviceProvicedListArray?.objectEnumerator().allObjects as? [[String:Any]]
let count = dicArray?.map({ Int($0["lstActType"] as? String ?? "0")! }).first!
The batter approach is to use guard or if let and wrapped the dicArray.
guard let dicArray = serviceProvicedListArray?.objectEnumerator().allObjects as? [[String:Any]] else {
print("Not array of dictionary")
return
}
guard let count = dicArray.map({ Int($0["lstActType"] as? String ?? "0")! }).first else {
return
}
print(count)
Or you can add both the guard let statement in single guard statement like.
guard let dicArray = serviceProvicedListArray?.objectEnumerator().allObjects as? [[String:Any]],
let count = dicArray.map({ Int($0["lstActType"] as? String ?? "0")! }).first else {
return
}
print(count)
Edit: The reason you are facing this issue is because may be you are using NSDictionary and NSArray, if you use swift's native type it will be a lot easy for you to get/access the value.You can get UserID like this way.
guard let dict = data as? [String:Any],
let loginDict = dict["UserLoginResult"] as? [String:Any],
let userId = loginDict["UserID"] as? Int else {
return
}
let strUserId = String(userId)
Edit: The problem is you need to tell complier the type of objects resultObjectItems array have, so try like this way.
if let resultObjectItems = self.serviceProvicedListArray!.value(forKey: "lstActType") as? [[[String:Any]]] {
for i in 0..<resultObjectItems[0].count {
let resultObjectItem = resultObjectItems[0][i] as AnyObject
self.serviceProvicedList!.add(resultObjectItem)
}
}

Optional displayed on label since Swift 3 upgrade

My code was working perfectly with Swift2 and now for some label the variable is displayed but with Optional(....) just before...
Good code on Swift 2
var sstitre1:String!
print(sstitre1)
There is a perform segue which populate a value to sstitre1.
var sstitre1:String?
sstitre1 = json[21].string
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "hugo"
{
if let destinationVC = segue.destination as? MonumentViewController{
destinationVC.sstitre1 = "\(sstitre1)"
}
}
}
With Swift3, i ve get :
Optional(.....)
I want to get rid of Optional.
So i have as recommend on several post from stackoverflow, made some code change.
var sstitre1:String!
If let espoir = sstitre1 {
print (espoir)
}
But unfortunately it still displays Optional....
Pretty weird ....
In the line
destinationVC.sstitre1 = "\(sstitre1)"
always a literal string "Optional(foo)" is assigned to destinationVC.sstitre1 assuming the variable contains "foo"
The solution is to remove the String Interpolation
destinationVC.sstitre1 = sstitre1
PS: You should really use more descriptive variable names