How to read associative array sent from cloud code in iOS sdk? - ios

I have a cloud code function on Parse.com and I receive following response, can anybody please tell me how to read it in iOS code ?
{"result":[{"week":1,"avg":50.5},{"week":2,"avg":0},{"week":3,"avg":0},{"week":4,"avg":29},{"week":5,"avg":0},{"week":6,"avg":0},{"week":7,"avg":0}]}
Thanks.

Reply from cloudcode are already decoded into NSDictionary / NSArray compatible object or possibly mapped subclasses of PFObject if you have registered them.
Do NSLog(#"reply from parse : %#",reply); in cloud function block to see that data are already parsed.
You should be then able to process data like
for (NSDictionary * currentWeek in reply) {
....
}

Related

Trying to figure out CompletionHandler in Swift?

So I'm trying to do some programming with Phillips HUE lights and I've already made a bridging header and imported the necessary info to use the Hue SDK with Swift, but all of the guidance is written for Objective-C. I'm having trouble understanding/declaring this function in Swift:
// Start search for bridges
[self.bridgeSearch startSearchWithCompletionHandler:^(NSDictionary *bridgesFound) {
// Search is complete, handle results (dictionary contains IP and mac addresses of bridges found)
[self showBridgesFound:bridgesFound];
}
When I go to call this in Swift, I type bridgeSearch.startSearch() and Xcode automatically adds this with a Completion handler
//Search for bridges
let bridgeSearch: PHBridgeSearching = PHBridgeSearching()
bridgeSearch.startSearch { ([AnyHashable : Any]?) in
//code
}
I know how to get the information (found IP addresses) stored into an NSDictionary in Obj-C, but I'm not sure what to do here in terms of storing the IP addresses into some sort of data structure.
Thanks!
The problem is merely that you have not given the incoming parameter any name. Give it one:
bridgeSearch.startSearch { bridgesFound in
// code involving bridgesFound
}

PFFile and JSON?

In my chatting application, I'm using Parse for a user table, getting ID's, images, etc. I recently added this functionality, and I have encountered a problem. When I send a message, I create an NSDictionary with information about the message such as time, message, sender, sender objectId, etc. But, when I try to add the PFFile (image file) associated with the user, I get an error saying that PFFile cannot be converted to JSON (PubNub message format). How can I add PFFile as part of the NSDictionary used in the message to be compatible with JSON, or there might be another way.
I'm not familiar with asynchronous tasks, but in my code, I have a method - (NSDictionary *)parseMessageToDisplay:(NSDictionary *)message {} where the input would be message received from PubNub, and it would return a format better united to be displayed in a UITableView. If I added the ID of the file or user to my dictionary, how could I get my image in UIImage or NSData, and return it from my method in an NSDictionary. Sorry if this post seems long, just trying to provide a lot of information.
In order to use parse.com, PFFile in particular, you'll probably want that NSDictionary to be a PFObject instead. A PFFile reference can be saved as an attribute of a PFObject -- in fact that's the only way it can be saved.
Thanks to #danh for this suggestion, but you really saved me. Apparently Parse creates a URL for all PFFiles and I can just send that URL (NSString *) with my NSDictionary to PubNub, and then in my - (NSDictionary *)parseMessageToDisplay:(NSDictionary *)message method just use [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURLString]]; and get data from that. YAY! No long running confusing asynchronous tasks to made my day terrible!

Get NSString out of ENNoteContent with Evernote Cloud SDK 2.0

I am new to Evernote SDK development and am using the evernote cloud SDK 2.0 as recommended by Evernote.
However, I am having trouble to get the NSString content out of the ENNoteContent object. I have tried the followings from searching online but none seems to work with the cloud sdk as I guess they are all for the old version of Evernote SDK...
1 Using "convertENMLToHTML" method.
According to this and this, I could call convertENMLToHTML directly on an ENNoteContent object much like this convertENMLToHTML:note.content. However, in the cloud SDK, this resulted in an exception inside ENMLUtility that terminates the app because convertENMLToHTML is expecting an NSString as opposed to ENNoteContent and the first thing this function does is trying to call [enmlContent dataUsingEncoding:NSUTF8StringEncoding]] which caused the exception if enmlContent is a pointer to ENNoteContent but not a pointer to NSString.
2 Attempting to get _emml object out of the ENNoteContent object
This post has a quote of calling [note.content enml] but this again doesn't work with cloud sdk as object enml isn't defined in the interface.
Does anyone know how one can get an NSString out of ENNoteContent? I would expect this to be a very straightforward process but am surprised that I wasn't able to find anything that works for the Cloud SDK.
3 Using generateWebArchiveData method
Per Sash's answer below, I have also attempted to use the generateWebArchiveData method in the example from the cloud sdk. The code I have looks like this:
[[ENSession sharedSession] downloadNote:result.noteRef progress:^(CGFloat progress) {
} completion:^(ENNote *note, NSError *downloadNoteError) {
if (note) {
NSLog(#"%#", note.title);
[note generateWebArchiveData:^(NSData *data) {
NSString* strContent = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"test content %#", strContent);
}];
} else {
NSLog(#"Error downloading note contents %#", downloadNoteError);
}
}];
However, strContent outputs "null" for a note that I have verified with legitimate content.
As a temporary hack, we added #property (nonatomic, copy) NSString * emml;
in ENNoteContent.h and removed the same line in ENNoteContent.m to get around this for now.
You are close. Technique #1 above is what you want, but as you discovered the enml property is private in the "default" SDK. Import the "advanced" header and you'll have access to note.content.enml. That is a string, and you can send it to convertENMLtoHTML if you prefer an HTML representation.
Do note that there is no "plaintext" string content for an existing note. You'll always see it as markup, and if you want to get rid of the markup, doing so is beyond the scope of the SDK-- how to do that depends very much on what the content you're dealing with looks like.
You should check out their samples included with SDK, seems like
-[ENNote generateWebArchiveData:] will get you HTML NSData in the completion block
https://github.com/evernote/evernote-cloud-sdk-ios/blob/master/Getting_Started.md#downloading-and-displaying-an-existing-note might also help

How do I "box" a PFObject inside an iOS push notification?

I want to send a PFObject directly over a push notification. I send the Parse object directly inside the push (e.g. with a custom key "arg") but I couldn't figure out how to construct a real PFObject from the received data. Received data is (obviously) an NSDictionary, with all the keys (object ID, created at, ACLs etc) available. How do I convert it to a PFObject instance?
I need a real way to construct a PFObject with the available data, so don't come with obvious solutions like "send the object ID and then fetch that object at client with Parse's methods." etc. I already know that obvious solution, but it's time/bandwidth/quota inefficient as it requires a new query, while I can have everything I need in that query anyway.
I'm looking for an automatic way, if any. I am targeting iOS 8 so maximum push payload size is also not an issue (2KB is more than enough for my case).
UPDATE: I've tried [PFObject objectWithClassName:#"MyClassName" dictionary:receivedDictionaryObject]; but no avail. It just does not work, the fields are nil even though the dictionary has all the data directly from Parse itself.
I think you can use something like this
+ (PFObject *)objectFromDictionary:(NSDictionary *)dictionaryFromPush{
PFObject *theObject = [[PFObject alloc] initWithClassName:#"MyClassName"];
for( NSString *keys in [dictionaryFromPush allKeys] )
{
[theObject setObject:[dictionaryFromPush objectForKey:keys] forKey:keys];
}
return theObject;
}
This is an untested code but im pretty sure will give you and idea of my point, to get the NSDcitionary from the Push and sent it to this method to be able to convert it to a PFObject
Hope this help

How do I get a server timestamp from Firebase's iOS API?

I have an iOS app that uses Firebase and currently has a few dictionaries with keys that are NSDate objects. The obvious issue with this is that NSDate draws from the device's system time, which is not universal.
With that, what's the best way to get a server timestamp (similar to Firebase.ServerValue.TIMESTAMP for the Web API) using Firebase's iOS API so that I can sort my dictionary keys chronologically?
I'm also aware of the chronological nature of IDs generated by childByAutoID, but I can't figure out the proper way to sort these in code. While they may be returned in chronological order, any time something like allKeys is called on them, the order goes out the window.
Any help with this issue would be greatly appreciated!
Update: In Firebase 3.0 + Swift, you can use
FIRServerValue.timestamp(). In Objective-C this is [FIRServerValue timestamp].
In Swift, you can now use FirebaseServerValue.timestamp() with Firebase 2.0.3+ (before 3.0).
The equivalent for Firebase.ServerValue.TIMESTAMP in iOS is kFirebaseServerValueTimestamp. Right now, this only works for Objective-C and not Swift.
In Swift, you can create your own global timestamp with
let kFirebaseServerValueTimestamp = [".sv":"timestamp"]
and then you'll be able to use kFirebaseServerValueTimestamp in the same way.
But you can only use this as the value or priority of a node. You won't be able to set it as the key name (although, I don't believe you could in the Web API either).
In general, calling allKeys on a dictionary does not guarantee order. But if you're using childByAutoID at a node, you can get back the right order by ordering the NSArray returned by allKeys lexicographically. Something like this would work:
[ref observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
NSDictionary *value = snapshot.value;
NSLog(#"Unsorted allKeys: %#", value.allKeys);
NSArray *sortedAllKeys = [value.allKeys sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"Sorted allKeys: %#", sortedArray);
}];
This is similar to sorting an NSArray alphabetically, but when sorting the auto-generated IDs, you do not want localized or case insensitive sort, so you use compare: instead of localizedCaseInsensitiveCompare:
Caveat: Seems like the timestamp is added AFTER your object is persisted in Firebase. This means that if you have a .Value event listener set up on the location your object is persisted to, it will be triggered TWICE. Once for the initial object being stored in the location, and again for the timestamp being added. Struggled with this issue for days :(
Helpful information for anyone else who can't figure out why their event listeners are triggering twice/multiple times!
As of Firebase 4.0 you can use ServerValue.timestamp()
for example:
let ref = Database.database().reference().child("userExample")
let values = ["fullName": "Joe Bloggs", "timestamp": ServerValue.timestamp()] as [String : Any]
ref.updateChildValues(values) { (err, ref) in
if let err = err {
print("failed to upload user data", err)
return
}
}
You can get Time Stamp using FIRServerValue.timestamp().
But, Because of FIRServerValue.timestamp() listener is called two times. Listener will be called two times.

Resources