Swift 4 - querying facebook with FBSDKGraphRequest - ios

I try to create a function for querying the Facebook database. Unfortunately, the syntax changed with the last version of swift. Maybe someone can post me the solution ?
Thx.
Func donneesFB

It's a lot easier to help you if you post your code as text instead of in an image.
Two things that will likely help you out here:
First, cast your result to the type of dictionary you are expecting before trying to access it:
guard let resultDict = result as? [String:Any] else { return }
You should now be able to use it like you tried to:
let nom = resultDict["name"] as? String
Secondly, for the error on your first line, simply get rid of the argument labels, nom, prenom and so on, leaving just the types.

Related

Firebase's snapshot.value cast to Bool suddenly returning nil

So my code was working perfectly fine but today it is returning nil when I try to cast Firebase's snapshot.value to a Bool. I haven't made any change to code at all. But it works fine if I cast it to a String (as? String returns "true").
Same issue at another place where I was casting to [String: Bool].
One thing that is different from earlier, I installed Xcode 10 beta 3 today (Xcode 9.4 is installed too). Both Xcode versions are returning nil. Here's the code:
if let currentUserId = Auth.auth().currentUser?.uid{
Database.database().reference().child("users/\(currentUserId)/share").observe(.childAdded) { (snapshot) in
let data = snapshot.value as? Bool
if data == true{
self.showNotificationsBadge()
}
}
}
Edit: Snapshot is not nil. You can see that in the console pane. I have printed both snapshot.key and .value.
Edit 2: I'm sorry if my question caused any confusions. The main purpose of this question is to know the problem, is it Firebase SDK or Xcode. Because it was working perfectly till now. I know how I can tackle this and how can I convert a String to a Bool.
Edit 3: Thank you everyone for your answers. I'm sorry I was unable to deliver my thoughts correctly. I just want to know about this unpredicted behavior and why is it happening? Who is the culprit here? Xcode, Firebase SDK? This code worked PERFECTLY FINE for about a month. I'm not asking for a solution, I'm just curious about this behavior. It would be great if someone from team Firebase can explain this issue.
Edit 4: Removed image and added code. Also figured out the issue thanks to #Jay's comment.
You need check if the snapshot is nil before checking the value.
if let data = snapshot.value as? Bool {
....
}
This happened to me just recently. I discovered that I had quotes around the child value, eg. "true". Remove the quotes and the solution from #Maximo should work as expected.

Kinvey 3.3.5 SDK Query By Ids

I am currently going through the processes of migrating swift 2.3 to 3 using the most updated Kinvey SDK (version 3.3.5). They have done a ton of updates since the 1x versions. My question is has anyone successfully been able to query on the PersistableKeyID field and pull multiple objects?
I use to be able to use the "loadObjects" function which would take an array of strings as an argument. This function has since been depreciated and replaced with find(byId). See below:
dataStore.find(byId: "only takes one") { uClass, error in
if let uClass = uClass {
//succeed
print("UClass: \(uClass)")
} else {
//fail
}
The issue is, it will only take a single string as an argument. I have attempted to use the query functionality, but I cannot get it to take the "_id" field as a parameter. Using the following code:
//Just statically creating the sectionID array for now. This will dynamically be created
testIDs = ["58668307206c11177e5ab0d4", "58668307206c11177e5ab0d4", "57ad00a505a2bb55632659c3"]
let sectionStore = DataStore<Section>.collection()
let sectionQuery = Query(format: "_id IN %#", testIDs)
sectionStore.find(sectionQuery) {sectionResult, error in
if let sectionResult = sectionResult {
self.sectionsTest = sectionResult
self.sectionCollectionView.reloadData()
} else{
//Error
}
}
I receive the error:
'Invalid property name', reason: 'Property '_id' not found in object of type 'Section'
Anyone have an idea on how to perform this now that "loadObjects" has been depreciated? There is no delivered "find(byIds)" that I could find.
Jbone107,
I was able to get results with this, let me know if the below works for you.
let id:[String] = ["5855026650a816ec29012908","5855024a21400c5b492bea20"]
let query = Query(format: "_id IN %#", id)
dataStore.find(query) { data, error in
if let data = data {
//succeed
print(“Data: \(data)")
} else {
//fail
print("fetching failed")
}
}
Thanks,
Pranav,
Kinvey
Answered: Per the Data Store Guide for iOS, by default the ".collection()" is of type "cache". The "Cache" type will store data locally. This must be why "Realm" is now included with the version 3x SDK.
I updated my DataStore collection to:
let sectionStore = DataStore<Section>.collection(.network)
I added ".network" to force the query to pull from the backend rather than the cache file. This actually identified "_id" as a property and the query worked successfully. For some reason the "cache" file isn't storing this as a property.
Additional SDK Question Answered
I was having an issue pulling NSNumber from the Kinvey backend. This ended up being a similar issue related to the "cache" query. I reviewed the Realm support site as a last resort effort to try and figure this out. I found that Realm doesn't actually support type "NSNumber".
Excerpt taken from: https://realm.io/docs/swift/latest/
Realm supports the following property types: Bool, Int8, Int16, Int32, Int64, Double, Float, String, NSDate, and NSData.
Unfortunately, Kinvey doesn't support "Int" types. As a work around, I have changed them to string and am just converting back to "Double" or another type after I pull the data. However, if I just use ".network" collection types, then NSNumber still works.
Thanks,
James

CoreData - Safely Check Value of CoreData Object

The way I currently have my code arranged, the following line will run for various managed-object-contexts. Some of the fetched entities will have "complededDate" and others will not have a "completedDate" attribute.
let task = retrieved_MgObjCntxt[(indexPath as NSIndexPath).row]
if let itemFinDate = task.value(forKey: "completedDate") {
...
I thought by using if-let, that if this failed then it'd be okay... but I'm getting an "lldb" crash. I've been playing with trying to solve it using do/catch and throw but I'm not super familiar with how those work.
Is there a way to safely check so that if "completedDate" doesn't exist, it just skips the code within the if-closure??
let task = retrieved_MgObjCntxt[(indexPath as NSIndexPath).row]
if task.entity.propertiesByName.keys.contains("completeDate") {
...
}
You can find all the keys for you objects entity type by using:
managedObject.entity.attributesByName
And then see if that dictionary's keys contains "completedDate"

What is wrong with this line of Swift iOS Code?

I have created an iOS app using Swift and everything is working fine and dandy on the simulator. I get no errors or crashes at all, but when I submit my app to put up on the app store Apple rejects it and lets me know that it crashes when the user makes a selection. I cannot recreate this error/crash. I took the crash logs and symbolicated them. This line of code came up as the culprit for the crashes:
linksToPass = getLinks(season) as [String:[String]]
This line is trying to store the resulting Dictionary from the getLinks() function I created. It for sure is getting a dictionary and if there is no dictionary to send back I create a dictionary which has error information in it, so it is for sure returning a dictionary in that format no matter what. Seeing as I cannot recreate the crash, I am just trying to error check this line of code in any way possible so it does't crash when I resubmit to Apple.
I tried checking if the resulting dictionary was nil like so:
if(getLinks(seasons) != nil){
linksToPass = getLinks(season) as [String:[String]]
}
This is not valid though, and XCode lets me know that UInt8 is not compatible with NSDictionary or something of that nature.
I then fixed that line and changed it to this:
if(getLinks(seasons) != ["":[""]]){
linksToPass = getLinks(season) as [String:[String]]
}
I am just not sure if this is even a good way to check for errors. I was wondering if there were any suggestions on how I may go about making sure this line does not fail and result in a crash. Thank you very much.
EDIT:
Here is my getLinks() function if that helps add more info to the problem:
var season = ""
let hymn_links = Hymn_Links()
func getLinks (nameofseason:String) -> NSDictionary
{
switch (nameofseason)
{
default:
return ["Maps Not Found": []]
}
}
EDIT #2:
This is my updated getLinks() function with the use of optionals.
func getLinks (nameofseason:String) -> NSDictionary?
{
switch (nameofseason)
{
default:
return nil
}
}
Also in my statement of linksToPass I changed it to:
if let links = getLinks(season) as? [String:[String]]
{
linksToPass = links
hymnnames = [String] (linksToPass.keys)
}
There are some known issues with the Swift optimiser. Some people have resorted to shipping with debug builds.
My suggestion would be to test with an optimised build to see if you can reproduce it. You can then try shipping a debug build to the App store.
General Code Comments
Why are you returning an NSDictionary rather than a Swift dictionary anyway? Without knowing the contents and creation method for your hymn_links object I can't be sure how good it is.
I would avoid as casts until Swift 1.2 and stick to using as? and then handling the nil case. At least in your "Edit 2" a nil will cause a crash as nil cannot be cast to [String:[String]] although [String:[String]]? should be possible.
Can you guarantee that all of the items returned by the switch statement will never under any circumstances be nil? If not getLinks should return an Optional.
Note that is is virtually impossible for getLinks to know that one of the items will never be nil and in Swift un-handed nils are a crash waiting to happen. Unless all these methods correctly handle nil.
Return an Optional and handle that in the statement that calls getLinks.
Languages handle nils differently, Objective-C handles them rather well, Java and Swift by crashing. But Swift has a mechanism to handle nils without crashing: Optionals, use it.

parsing json in swift

I'm trying to read the Linkedin response in swift.
My object is something like this ["positions":["values":["data1","data2","data3"]]]
if let positions: NSDictionary = info["positions"] as NSDictionary!{
if let positionsInfo: [NSDictionary] = positions["values"] as? [NSDictionary]{
for position : NSDictionary! in positionsInfo {
dosomething(position, person:usr)
}
}
}
If I do a StepOver line by line it works correctly. But if I run it i'll get a EXC_BAD_ADDRESS(code=1,address=0x7966b04) I enabled Zombie objects and ran it on Instruments. I'm pretty sure this is the code which is causing the problem. But not sure what is wrong with it.
The moment you used ! you opened yourself up for crashes if there were any problem. You must use as? to make sure that the data is actually what you think it is.
There are many blog posts out there on how to safely parse JSON into Swift data structures. It's now almost a rite of passage for Swift bloggers.
http://robots.thoughtbot.com/efficient-json-in-swift-with-functional-concepts-and-generics
http://chris.eidhof.nl/posts/json-parsing-in-swift.html
https://github.com/owensd/json-swift
https://github.com/lingoer/SwiftyJSON
Of course the many packages: https://github.com/search?q=%5Bswift%5D+json
http://robnapier.net/functional-wish-fulfillment - My own version on top of all the others

Resources