Why is EDAMNote.content is null? - ios

I want to get the content of the first note in the notebook. I set a content and title. Title is ok but content attribute is null.
EDAMNoteFilter *filter = [[EDAMNoteFilter alloc] init];
[[EvernoteNoteStore noteStore] findNotesWithFilter:filter
offset:0
maxNotes:10
success:^(EDAMNoteList *result) {
if(result.totalNotes>0)
{
EDAMNote *note=result.notes[0];
NSLog(#"%#",[note title]);
NSLog(#"%#",[note content]);
}
}
failure:^(NSError *error) {
// FIXME:zxx 2012-9-26 Alert user error occurs
NSLog(#"Error occurs when retreiving notes: %#", error);
}];

If you read the documentation for the findNotesWithFilter method in the Evernote SDK you will see the following -
Discussion
Used to find a set of the notes from a user’s account based on various
criteria specified via a NoteFilter object.
The Notes (and any embedded Resources) will have empty Data bodies for contents, resource data, and resource recognition fields. These values must be retrieved individually.
You need to retrieve the content using a method such as getNoteWithGuid:withContent:withResourcesData:withResourcesRecognition:withResourcesAlternateData:success:failure:

Related

Google API Bug - Attribution Inconsistency

Fetching photo data for a place using Google Places API HTTP web service call URL,
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=<LOCATION>&radius=<RADIUS>&sensor=false&key=<API_KEY>
yields the expected callback. Here is the response from a request I am using for testing.
2017-09-19 11:20:32.968347-0400 <MY_APP_NAME>[7502:2809094] Places Found: (
{
...
...
photos = (
{
height = 5312;
"html_attributions" = (
"leah steen"
);
"photo_reference" = "CmRaAAAAcppPDrYGBnLqlyYQ_EMmsvgKXXpVjp0drGkJPWLBwlSzrWzuhtFFGCzQPl1pSez92QVktthtaMSsV1IlAWMIMPboycElhruKgUg-KFHWWrhLKOR6h8GGiR349rhokAFJEhApc7ghYIH0guUQBGJi1bKBGhQMcElN7-lSBzvCgAG3vVzANLkf6A";
width = 2988;
}
);
...
...
}
)
As you can see, this place has a photo dictionary containing an html_attributions value for the associated image, which I am handling appropriately throughout my application.
ISSUE:
When I fetch the photo data for the same place, by using the place_id, I get this for the photo and attribution:
2017-09-19 11:22:08.548253-0400 <MY_APP_NAME>[7502:2809094] photo data: (
"<UIImage: 0x17048b720> size {169, 300} orientation 0 scale 2.000000",
"leah steen{\n}"
)
I receive of course the same photo, but an attribution WITHOUT a link. As you can see from my other method using the web service, the photo for this place does indeed have an attribution with a link.
I am at a loss. How am I supposed to get the full attribution from Google if their iOS SDK does not return the same data?
CODE:
Using Google's other suggested method for fetching photo data for a place via the place_id you can obtain the image and the images attribution (if it has one).
I fetch the data using these two methods as Google asks:
- (void)lookUpPhotosForPlaceID:(NSString *)placeID
callback:(GMSPlacePhotoMetadataResultCallback)callback;
- (void)loadPlacePhoto:(GMSPlacePhotoMetadata *)photo
callback:(GMSPlacePhotoImageResultCallback)callback;
Here is the code I use for fetching the photo data.
// Look up photos for the place
[[GMSPlacesClient sharedClient] lookUpPhotosForPlaceID:placeID callback:^(GMSPlacePhotoMetadataList * _Nullable photos, NSError * _Nullable error) {
if (error != nil) {
response(error, NULL);
return;
}
if (photos.results.count > 0) {
GMSPlacePhotoMetadata *metaData = photos.results.firstObject; // Using the first photo
// Load the photo
[[GMSPlacesClient sharedClient] loadPlacePhoto:metaData constrainedToSize:<SOME_SIZE> scale:[UIApplication sharedApplication].keyWindow.screen.scale callback:^(UIImage * _Nullable photo, NSError * _Nullable error) {
if (error) {
response(error, NULL);
return;
}
NSArray *photoData = #[photo, metaData.attributions];
response(nil, photoData);
}];
}
else response(error, NULL);
}];
EDIT:
For reference, as Google does inform it's users that this data may be subject to change, and that multiple callbacks should return the same data. Yet multiple calls using different API's do not...
You can do couple of thing to verify correct behaviour:
You can switch back to first API and see whether it actually returns it again. Because doc says:
Multiple calls of this method will probably return the same photos
each time. However, this is not guaranteed because the underlying data
may have changed.
Second you can check the callback behaviour if you are losing some data when callback is called in line
NSArray *photoData = #[photo, metaData.attributions];
At this point it me be loosing attributed string but only retains plain text(leah steen).
Good way to check this metaData is before loadPlacePhoto:callback:

Unpinning HomeKit accessory

The HomeKit Accessory simulator as a wee little botton that allows to unfair the device.
Given it's an accessory simulator I presume that there are some hardware programming specifications that allow to write an un-pairing function.
However, it could make sense to implement this also as part of the HomeKit framework and allow client developers to do it via the HomesController class (and derivates).
--> short version:
Is there any method in HMService or HMCharacteristic or in the HomeKit framework to unpair a characteristic/service from a home?
Service or Characteristic can not be unpair, practically its not require to do.
One can unpair Accessory from home.
You can call method of HMHome class to remove/unpair accessory.
- (void)removeAccessory:(HMAccessory *)accessory
completionHandler:(void (^)(NSError *error))completion;
And Pairing - Reset button is given in Homekit Accessory Simulator for an option, you can always unpair the accessory from an iOS app.
Reset may require if you don't have the same device at a time or the Homekit configuration is reseted from settings in iOS app.
Unpairing is equivalent to essentially removing that accessory from under a HomeKit home (HMHome). That can be achieved by using the api call under HMHome (could be triggered by a button click from your view controller let's say):
Sample code:
[yourHMHome removeAccessory:accessory_ completionHandler:^(NSError *error) {
if (error) {
//Handle your error here.
} else {
//Removing, or here, un-pairing was successful, do anything else
//Example
[[YourExampleHomeStore sharedStore] updateAccessoryDelegates];
YourCompletionHandler(error);
}
}];
That answers your question regarding un-pairing. HMService and HMCharacteristic is conceptually different. If you'd like to update the value of a (writeable) HMCharacteristic, then you'd search for that HMCharacteristic in the available HMServices. Remember, the available HMServices and thus HMCharacteristics on an accessory will be completely different based on its paired state. Most read or writes and 'paired-read' and 'paired-write', and when in un-paired state, you can only read the 'accessory information service' (name, model etc.)
Now, presuming that you'd like to read or change (write) the value of a HMCharacteristic, let's say it's the serial number, the steps would be:
Get the pertinent HMCharacteristic
Sample code for serial number could be something like this:
Note: Returns empty string if accessory is unreachable.
+(NSString *)getSerialNumberFromHMAccessory:(HMAccessory *)accessory
{
if (!accessory || !accessory.reachable) { return #""; }
for (HMService *service in accessory.services) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K like %#", #"characteristicType", HMCharacteristicTypeSerialNumber];
NSArray *result = [service.characteristics filteredArrayUsingPredicate:predicate];
if (result && [result count] > 0 && [result[0] isKindOfClass:[HMCharacteristic class]]) {
HMCharacteristic *serialNumChar = (HMCharacteristic *)result[0];
NSString *serialNum = [serialNumChar valueForKey:#"value"];
if (serialNum && [serialNum length] > 0) {
NSLog(#"Found serial number: %# for accessory named \"%#\"", serialNum, accessory.name);
return serialNum;
}
}
}
return #"";
}
Once you've found your desired HMCharacteristic, you can make HomeKit api calls to further your interest (like update value etc.). Here, since serial number is not writeable, you need to be content with just reading it.
Anyway, probably ranted a tad too long and digressed from the main question. Hope this helps you man. Cheers.

removeTracksFromPlaylist not removing tracks with ios spotify sdk

I was testing this method to remove tracks from a playlist. Basically I modified the demo project "simple track playback" provided with the SDK. I wanted to remove the track form the playlist when you hit fastForward. I changed the fastForward method this way but it's not doing anything, and error is nil.
-(IBAction)fastForward:(id)sender {
if([self.player isPlaying] && self.currentPlaylistSnapshot){
SPTAuth *auth = [SPTAuth defaultInstance];
[self.currentPlaylistSnapshot removeTracksFromPlaylist:#[self.player.currentTrackURI]
withAccessToken:auth.session.accessToken
callback:^(NSError *error) {
if (error != nil) {
NSLog(#"*** Failed to remove track : %#", self.titleLabel.text);
return;
}
}];
}
[self.player skipNext:nil];
}
self.currentPlaylistSnapshot is the one I've got from the handleNewSession method.
There's also a static method apparently offering something similar which I have't tried yet.
createRequestForRemovingTracks:fromPlaylist:withAccessToken:snapshot:error:
According to the documentation both options are implemented asynchronously and will take seconds to reflect the results in the server but I'm suspecting that there's either something wrong or I'm just missing to do an actual request to push the changes on the local snapshot maybe?
Documentation:
https://developer.spotify.com/ios-sdk-docs/Documents/Classes/SPTPlaylistSnapshot.html#//api/name/removeTracksWithPositionsFromPlaylist:withAccessToken:callback:
ios sdk:
https://github.com/spotify/ios-sdk
I solved my issue by reseting simulator + adding SPTAuthPlaylistModifyPublicScope (which I fogot to do...)
auth.requestedScopes = #[SPTAuthStreamingScope, SPTAuthPlaylistModifyPublicScope];

iOS looping error

So I'm having a weird problem with loops in while developing in iOS. There are over hundreds of lines of code, so instead of boring you with it, I'm going to describe the problem.
I am trying to upload events from Facebook to an Microsoft Azure server. To do so, I made a class called FacebookUploader. In that class, I loop through the events of Facebook (and set all the variables to the class. ie. the name of the first event is self.event, when loops continues and goes to the second event, that events name is self.event now). What I expected iOS to do was to go through each event in the loop, upload it, and then move onto the next one.
This worked while I was just uploading the event. Now, I'm also first checking the database to see if the event is already there. And then when I get confirmation that it's not there, I upload it. However, when it comes time to upload it, Facebook Uploader has already finished looping through all the events and only the last event gets uploaded (multiple times, one for each event that should be uploaded).
I've pinpointed the error, now I'm asking, what am I doing wrong? Should the variable not be associated with the class and instead be local? Or is there a way to stop running the loop until we get confirmation from the server that the event is not there? Your help is much appreciated.
MSQuery *query = [self.table queryWithPredicate: [NSPredicate predicateWithFormat:#"fb_id == %#", self.id]];
[query readWithCompletion:^(MSQueryResult *result, NSError *error) {
//not in table, add it
NSArray *items = [result.items mutableCopy];
if (items == nil || [items count] == 0) {
NSDictionary *newItem;
if(self.end_time != nil) {
newItem = #{#"fb_id": self.id, #"event_name": self.name, #"event_location": self.location, #"event_start": self.start_time, #"event_end": self.end_time, #"event_description": self.descriptionOfEvent, #"picture_url": self.picture_url, #"event_latitude": self.venue_latitude, #"event_longitude": self.venue_longitude, #"popularity": self.popularity};
}
else {
newItem = #{#"fb_id": self.id, #"event_name": self.name, #"event_location": self.location, #"event_start": self.start_time, #"event_description": self.descriptionOfEvent, #"picture_url": self.picture_url, #"event_latitude": self.venue_latitude, #"event_longitude": self.venue_longitude, #"popularity": self.popularity};
}
[self.table insert:newItem completion:^(NSDictionary *result, NSError *error) {
// The result contains the new item that was inserted,
// depending on your server scripts it may have additional or modified
// data compared to what was passed to the server.
if(error) {
NSLog(#"ERROR %#", error);
} else {
NSLog(#"Todo Item: %#", [result objectForKey:#"event_name"]);
}
}];
}
The answer to the question was given by Paulw11 above. By allocating the variables outside of the loop, I was creating multiple copies of the variables, causing my error. Allocating the variable inside of the loop fixed the error.

iOS Facebook Native Share Dialog : initial text

I'm using Facebook Native Share Dialog in my iOS app. I give the initial text, but when dialog pop up, it add the post URL to my initial text. How can I solve this problem? Here the code.
BOOL displayedNativeDialog =
[FBNativeDialogs
presentShareDialogModallyFrom:self
initialText:#"Say something about this..."
image:[UIImage imageWithData:imageData]
url:[NSURL URLWithString:activityUrl]
handler:^(FBNativeDialogResult result, NSError *error) {
if (error) {
} else {
if (result == FBNativeDialogResultSucceeded) {
} else {
}
}
}];
If you're sharing a URL (link share) and the image is inside that link, then just set the image parameter to nil. Then the post URL will not be added to the initial text. If you provide an image, it's as if you're sharing a photo and adding the link (and text) as photo caption info.
So based on what you're trying to do, select the option that works for you, i.e. is it a link share or a photo share.

Resources