How to fetch photos from Picasa album? - xcode

I am developing an application which need to display photos from Picasa web album.
I have search about it. I got following links.
https://code.google.com/p/gdata-objectivec-client/
I have downloaded GData and also included all required folder into xcode.
The code which i have written is here.
- (void) loadPhotoGallery{
username = #"xyz";
password = #"abc";
GDataServiceGooglePhotos *photosService;
photosService = [self photoService];
NSURL *url = [GDataServiceGooglePhotos photoFeedURLForUserID:#"user" albumID:#"ablumID" albumName:nil photoID:nil kind:nil access:nil];
GDataQueryGooglePhotos *introspectQuery;
introspectQuery = [GDataQueryGooglePhotos photoQueryWithFeedURL:url];
[introspectQuery setResultFormat:kGDataQueryResultServiceDocument];
GDataServiceTicket *ticket;
ticket = [photosService fetchFeedWithQuery:introspectQuery delegate:self didFinishSelector:#selector(introspectTicket:finishedWithServiceDocument:error:)];
}
- (void)introspectTicket:(GDataServiceTicket *)ticket
finishedWithServiceDocument:(GDataAtomServiceDocument *)serviceDoc
error:(NSError *)error {
if (error == nil) {
GDataAtomCollection *collection = [[serviceDoc primaryWorkspace] primaryCollection];
NSArray *theMIMETypes = [collection serviceAcceptStrings];
}
}
-(GDataServiceGooglePhotos *)photoService{
static GDataServiceGooglePhotos *service = nil;
username = #"xyz";
password = #"abc";
if (!service) {
service = [[GDataServiceGooglePhotos alloc] init];
[service setShouldCacheDatedData:YES];
[service setServiceShouldFollowNextLinks:YES];
[service setIsServiceRetryEnabled:YES];
}
if ([username length] > 0 && [password length] > 0) {
[service setUserCredentialsWithUsername:username
password:password];
} else {
// fetch unauthenticated
[service setUserCredentialsWithUsername:nil
password:nil];
}
return service;
}
But i am very confused with this code.
Can anyone help. how to start code for fetching photos?
Thanks in advance.

I have resolve this. I have make two changes.
1. Edit loadPhotoGallery method
2. Create new method for fetching photos and displayed into grid.
My code for loadPhotoGallery is following.
- (void) loadPhotoGallery{
NSLog(#"fetchAllPhotos");
GDataServiceGooglePhotos *service = [self photoService];
GDataServiceTicket *ticket;
NSURL *feedURL = [GDataServiceGooglePhotos photoFeedURLForUserID:#"xyz#gmail.com" albumID:#"12345" albumName:nil photoID:nil kind:nil access:nil];
ticket = [service fetchFeedWithURL:feedURL delegate:self didFinishSelector:#selector(photosListTicket:finishedWithFeed:error:)];
feedURL = nil;
}
And code for displaying Photos into Grid is following.
-(void)displayGrid{
int x =0 ,y =0, counter =1;
for (int i=0; i<[self.photos count]; i++) {
GDataEntryPhoto *photoAlbum = [self.photos objectAtIndex:i];
GDataTextConstruct *textConstruct = [photoAlbum title];
NSString *stringTitle = [textConstruct stringValue];
NSLog(#"%#",stringTitle);
GDataMediaGroup *mediaGroup = [photoAlbum mediaGroup];
NSArray *arrMediaThumbs = [mediaGroup mediaThumbnails];
GDataMediaThumbnail *mediaThumbnail =[arrMediaThumbs objectAtIndex:2];
NSLog(#"%#", [mediaThumbnail URLString]);
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[mediaThumbnail URLString]]];
UIImage *img = [UIImage imageWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
imgView.frame = CGRectMake(x, y, 106, 106);
[scrPhoto addSubview:imgView];
UIButton *btn= [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = imgView.frame;
btn.tag = counter;
[btn addTarget:self action:#selector(btnPhotoClicked:) forControlEvents:UIControlEventTouchUpInside];
[scrPhoto addSubview:btn];
if(counter %3 == 0 ){
y = y +106;
x = 0;
} else{
x =x + 106;
}
counter++;
}
[scrPhoto setContentSize:CGSizeMake(320, y)];
}

Related

Facebook publish_actions deprecated

What can I do to use as an alternative to publish_actions? I have a photo app that lets users share their photos to their profile. Currently it uses logInWithPublishPermissions:#[#"publish_actions"] and then shares the files through FBSDKSharePhoto. But after August 1 this will be removed. Any thoughts? This is my current code but soon it won't work.
-(IBAction)loginToFacebook:(id)sender
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
login.loginBehavior = FBSDKLoginBehaviorWeb;
[login logInWithPublishPermissions:#[#"publish_actions"]
fromViewController:self
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(#"Process error");
} else if (result.isCancelled) {
NSLog(#"Cancelled");
nonpressTimer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:#selector(timeout) userInfo:nil repeats:NO];
} else {
NSLog(#"Logged in");
[self shareSegmentWithFacebookComposer];
}
}];
}
- (void)shareBoothOnFacebook {
NSUserDefaults *defaults2 = [NSUserDefaults standardUserDefaults];
NSData *data6 = [defaults2 objectForKey:#"layoutphoto"];
UIImage *myImage = [NSKeyedUnarchiver unarchiveObjectWithData:data6];
NSMutableArray *photos = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.arrSlidshowImg count]; i++) {
UIImage *image = [UIImage imageWithData:[_arrSlidshowImg objectAtIndex:i]];
FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
photo.image = image;
photo.userGenerated = YES;
[photos addObject:photo];
}
FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init];
content.photos = [photos copy];
[FBSDKShareAPI shareWithContent:content delegate:nil];
}
}
You'll need to switch to using Facebook's iOS sharing APIs which require that the Facebook Messenger app is installed. See their documentation on sharing.
You might also want to investigate the use of the iOS share sheet but that also requires the Facebook Messenger app to be installed to enable sharing to Facebook.

Block variable gets null outside of block - xcode

Im trying to carry over a block variable and put it in my convenience initializer but the variable returns null, can someone show me the right way of doing it, Thanks, also please check if I have done my NSComparison Result correctly, here's the code,
- (void) retrieveData
{
NSURL *url = [NSURL URLWithString:jsonFile];
NSData *data = [NSData dataWithContentsOfURL:url];
_jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
_salesArray = [[NSMutableArray alloc]init];
for (int i = 0; i < _jsonArray.count; i++) {
NSString *sID = [[_jsonArray objectAtIndex:i] objectForKey:#"id"];
NSString *sName = [[_jsonArray objectAtIndex:i] objectForKey:#"name"];
NSString *sAddress = [[_jsonArray objectAtIndex:i] objectForKey:#"address"];
NSString *sPostcode = [[_jsonArray objectAtIndex:i] objectForKey:#"postcode"];
__block NSString *distance;
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder geocodeAddressString:sPostcode completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil && placemarks.count > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocation *myLocation = self.manager.location;
CLLocationDistance miles = [location distanceFromLocation:myLocation];
//this is the variable i want in my convenience init.
distance = [NSString stringWithFormat:#"%.1f m", (miles/1609.344)];
}
}];
[_salesArray addObject:[[sales alloc] initWithSales:sID andName:sName andAddress:sAddress andPostcode:distance]];
}
[_salesArray sortUsingComparator:
^NSComparisonResult(id obj1, id obj2){
sales *p1 = (sales *)obj1;
sales *p2 = (sales *)obj2;
if (p1.postcode > p2.postcode) {
return (NSComparisonResult)NSOrderedDescending;
}
if (p1.postcode < p2.postcode) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}
];
[self.tableView reloadData];
}
Thanks in advance to anyone that can help, this happens to be the last part of my app until completion :)
-[CLGeocoder geocodeAddressString:completionHandler:] runs the completion handler asynchronously and it won't run the block before the rest of that function finishes. distance doesn't "get null"; rather, it hasn't been set yet.
your block is run AFTER the function completes ... doesn't matter if the 'line of code' is after or before the block.
the solution is to have to block call a 'continuation' function:
e.g. instead of - (void) retrieveData
have - (void) beginRetrieveData, which calls the block and then have a - (void) finishRetrieveData, which is called by the block and doesn't run before the block ;)
here is how your code could look:
- (void) beginRetrieveData
{
NSURL *url = [NSURL URLWithString:jsonFile];
NSData *data = [NSData dataWithContentsOfURL:url];
_jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
_salesArray = [[NSMutableArray alloc]init];
for (int i = 0; i < _jsonArray.count; i++) {
NSString *sID = [[_jsonArray objectAtIndex:i] objectForKey:#"id"];
NSString *sName = [[_jsonArray objectAtIndex:i] objectForKey:#"name"];
NSString *sAddress = [[_jsonArray objectAtIndex:i] objectForKey:#"address"];
NSString *sPostcode = [[_jsonArray objectAtIndex:i] objectForKey:#"postcode"];
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder geocodeAddressString:sPostcode completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil && placemarks.count > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocation *myLocation = self.manager.location;
CLLocationDistance miles = [location distanceFromLocation:myLocation];
//this is the variable i want in my convenience init.
NSString *distance = [NSString stringWithFormat:#"%.1f m", (miles/1609.344)];
[self finishRetrieveData:distance]; //continue
}
}];
}
}
- (void) finishRetrieveData:(NSString*)distance
{
[_salesArray addObject:[[sales alloc] initWithSales:sID andName:sName andAddress:sAddress andPostcode:distance]];
}

MapKit and adding new pins after a MKLocalSearch

I'm running a MKLocalSearch request and when I find POIs I want to drop a pin based on the coordinates of the POIs I find. NSLog(#"annotations %d",[mapView.annotations count]); returns 0 even with valid coordinates for the POIs
- (void)resultsForButtonTapped:(NSString *)search
{
arrayOfPOIs = [[NSMutableArray alloc] init];
arrayOfAnnotaions = [[NSMutableArray alloc] init];
NSLog(#"%#",search);
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
MKCoordinateRegion region;
request.naturalLanguageQuery = search;
request.region = region;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
localsearch = [[MKLocalSearch alloc] initWithRequest:request];
[localsearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if (error != nil) {
return;
}else{
if ([response.mapItems count] == 0) {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"No Results",nil)
message:nil
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK",nil) otherButtonTitles:nil] show];
return;
}
for (MKMapItem *item in response.mapItems)
{
NSString *name = item.name;
NSLog(#"%#",name);
[arrayOfPOIs addObject:name];
}
results = response;
NSLog(#"%d",[arrayOfPOIs count]);
for (int i=0; i<[results.mapItems count]; i++) {
MKMapItem* itemPOI = results.mapItems[i];
NSLog(#"Result: %#",itemPOI.placemark.name);
NSLog(#"Result: %#",itemPOI.placemark.name);
MKPlacemark* annotation= [[MKPlacemark alloc] initWithPlacemark:itemPOI.placemark];
MKPointAnnotation *marker = [MKPointAnnotation new];
marker.coordinate = annotation.coordinate;
[mapView addAnnotation:marker];
NSLog(#"annotations %d",[mapView.annotations count]);
}
[self loadTheDataAgain];
}
}];
// NSLog(#"outside the block, the count is %lu",(unsigned long)[arrayOfPOIs count]);
NSLog(#"stuff %#",arrayOfAnnotaions);
}

Several Hyperlinks in NSTableView Cell

At the moment I have an NSTableView with a custom NSTextFieldCell that holds an NSAttributedString with some ranges with the NSLinkAttribute. I tried to integrate code from Apple's TableViewLinks example and Toomas Vather's HyperlinkTextField.
I implemented the -trackMouse Function like this:
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag {
BOOL result = YES;
NSUInteger hitTestResult = [self hitTestForEvent:theEvent inRect:cellFrame ofView:controlView];
if ((hitTestResult & NSCellHitContentArea) != 0) {
result = [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:flag];
theEvent = [NSApp currentEvent];
hitTestResult = [self hitTestForEvent:theEvent inRect:cellFrame ofView:controlView];
if ((hitTestResult & NSCellHitContentArea) != 0) {
NSAttributedString* attrValue = [self.objectValues objectForKey:#"theAttributedString"];
NSMutableAttributedString* attributedStringWithLinks = [[NSMutableAttributedString alloc] initWithAttributedString:attrValue];
//HOW TO GET A RIGHT INDEX?
NSTableView* myTableView = (NSTableView *)[self controlView];
NSPoint eventPoint = [myTableView convertPoint:[theEvent locationInWindow] fromView:nil];
NSInteger myRow = [myTableView rowAtPoint:eventPoint];
NSRect myBetterViewRect = [myTableView rectOfRow:myRow];
__block NSTextView* myTextView = [[NSTextView alloc] initWithFrame:myBetterViewRect];
[myTextView.textStorage setAttributedString:attributedStringWithLinks];
NSPoint localPoint = [myTextView convertPoint:eventPoint fromView:myTableView];
NSUInteger index = [myTextView.layoutManager characterIndexForPoint:localPoint inTextContainer:myTextView.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
if (index != NSNotFound)
{
NSMutableArray* myHyperlinkInfos = [[NSMutableArray alloc] init];
NSRange stringRange = NSMakeRange(0, [attrValue length]);
[attrValue enumerateAttribute:NSLinkAttributeName inRange:stringRange options:0 usingBlock:^(id value, NSRange range, BOOL* stop)
{
if (value)
{
NSUInteger rectCount = 0;
NSRectArray rectArray = [myTextView.layoutManager rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer:myTextView.textContainer rectCount:&rectCount];
for (NSUInteger i = 0; i < rectCount; i++)
{
[myHyperlinkInfos addObject:#{kHyperlinkInfoCharacterRangeKey : [NSValue valueWithRange:range], kHyperlinkInfoURLKey : value, kHyperlinkInfoRectKey : [NSValue valueWithRect:rectArray[i]]}];
}
}
}];
for (NSDictionary* info in myHyperlinkInfos)
{
NSRange range = [[info objectForKey:kHyperlinkInfoCharacterRangeKey] rangeValue];
if (NSLocationInRange(index, range))
{
NSURL* url = [NSURL URLWithString:[info objectForKey:kHyperlinkInfoURLKey]];
[[NSWorkspace sharedWorkspace] openURL:url];
}
}
}
}
}
return result;}
The character-Index when clicking into the cell's (nstextview's) text appears not to fit. So even if there are more than one link in the text, usually the last link is opened. My guess is that I donĀ“t get the nsrect of the clicked cell. If so, how could I get the right NSRect?
I am glad for any suggestions, comments, code pieces - or simpler solutions (even if this would include switching to a view-based tableview).
Thanks.

calling a method when a particular CCAnimationFrame is displayed using CCAnimationFrameDisplayedNotification

I would like to call a method that rotates a sprite when a particular frame in displayed. I got a few ideas from this post but I am having issues as to how I should implement it. How would I define my dictionary for accessing 3rd frame and link it to the selector? Below is what I've done. Please note that it's work-in-progress.
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
CCSpriteBatchNode* batchNode;
CCSpriteFrameCache* frameCache;
frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
[frameCache addSpriteFramesWithFile:#"cat-hd.plist"];
batchNode = [CCSpriteBatchNode batchNodeWithFile:#"cat-hd.pvr.ccz"];
[self addChild:batchNode];
CCSprite* wallbg = [CCSprite spriteWithSpriteFrameName:#"firstBg.png"];
wallbg.position= ccp(240.0, 160.0);
//wallbg.anchorPoint = ccp(0.5, 0.5);
[batchNode addChild:wallbg];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(rotateAnimationFrame:) name:CCAnimationFrameDisplayedNotification object:nil];
NSMutableArray* catAnimationArray = [[NSMutableArray alloc]init];
for(int i = 1; i < 7; i++) // i< number of frames in the plist File Name
{
CCLOG(#"item %d added", i);
[catAnimationArray addObject:
[frameCache spriteFrameByName:
[NSString stringWithFormat:#"blackCat%d.png", i]]]; }
CCSprite* catSprite = [CCSprite spriteWithSpriteFrameName: #"blackCat1.png"];
CGSize screenSize = [[CCDirector sharedDirector] winSize];
catSprite.position = ccp(screenSize.width/2, screenSize.height/2);
CCAnimation *animation = [CCAnimation animationWithSpriteFrames:catAnimationArray delay:0.3];
CCAnimationFrame* thirdFrame = [animation.frames objectAtIndex:2];
NSDictionary* uInfo = //how should I define my dictionary?
id action =[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation :animation]];
[catSprite runAction:action];
[batchNode addChild:catSprite];
}
return self;
}
// on "dealloc" you need to release all your retained objects
-(void)rotateAnimationFrame:(NSNotification*)notification {
NSDictionary *userInfoDictionary = [notification userInfo];
if ([[notification name] isEqualToString:#"CCAnimationFrameDisplayedNotification"]) {
CCSprite* thirdAnim = [CCSprite spriteWithSpriteFrame:#"blackCat3.png"];
CCRotateTo *rotateRight = [CCRotateBy actionWithDuration:0.2 angle:40.0];
[thirdAnim runAction:rotateRight];
}

Resources