Random facebook profile id generator - xcode

Right I have a programme that displays a profile facebook profile picture when a button is touched accessed by using the graph api as shown. in the url:
http://graph.facebook.com/517418990/picture?type=large
The number can be changed to show a different profile picture (some numbers dont work but that is a different question. How in xcode can i firstly generate a random number (i assume it has to have some kind of structure not just a random 9 digit number) and secondly how can i load a new random number with each push of the button. E.g. push button = display profile of random number, push 2 = display profile of new random number etc etc. Some of the code below is not completely relevant because i also have an array with some images in it that to go through. Thanks in advance!
#interface FacebookPicturesViewController : UIViewController {
IBOutlet UIImageView *imageView;
NSInteger imageCount;
NSArray *imageArray;
NSString *profileLink;
}
- (IBAction) nextImagePush;
#end
#implementation FacebookPicturesViewController
(IBAction) nextImagePush {
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://graph.facebook.com/517418990/picture?type=large"]]];
[imageView setImage:img];
if (imageCount >= [imageArray count]){
imageCount = 0;
}
}
(void) viewDidLoad {
imageArray = [[NSArray alloc] initWithObjects:#"image1", #"image2", nil];
imageCount = 0;
}

Related

How to set a value for an image

I am using a switch statement to fill imageviews with pictures at random.
Now I am trying to give the pictures a value. That way I can use that value to make comparison. Can somebody explain me how to give images a value?
I have used the following code to setup the array for the UIImages, but can't get it completely working: (.m file)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *image1 = [UIImage imageNamed:#"image-1.png"];
UIImage *image2 = [UIImage imageNamed:#"image-2.png"];
UIImage *image3 = [UIImage imageNamed:#"image-3.png"];
UIImage *image4 = [UIImage imageNamed:#"image-4.png"];
UIImage *image5 = [UIImage imageNamed:#"image-5.png"];
_imageArray = #[image1, image2, image3, image4, image5];
}
-(void)displayImageRandomlyOnView {
NSUInteger randomIndex = arc4random_uniform([_imageArray count]);
_imageToDisplay.image = [_imageArray objectAtIndex:randomIndex];
}
Have created also a button in the .h file, to call the view...but can't get the code working for the button calling the view.
If I now try to run the IS it crashes even without the button in it. Can somebody tell me what is going wrong?
The following information is in the .h file: (have left the button out)
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIImageView *imageToDisplay;
#property (strong, nonatomic) NSArray *imageArray;
That was really helpful! I have now created a button that will fill in total 10 UiImage views. 5 in the left side of the screen, UiImage view 1-5 and right side I have UiImage view 6-10. I created two separe array's to fill the right and the left side. The only thing I now want to do is to compare the UiImage view 1-5 against 6-10. If a UiImage view is filled with an image it should return value 1 and if not it should have 0. This way I can compare if the right or left side has more images filled or exactly the same. Can you point me in the right direction on how to do this? Thanks!
I would suggest storing the UIImages in an array, sorting them randomly, and then sequentially fill the UIImageViews with the images. This way you don't need to attach a value to the images as you know what position they are in the array from their position amongst your image views.
EDIT
You should replace the line
_imageArray = #[image1, image2, image3, image4, image5];
with
_imageArray = [[NSArray alloc] initWithObjects:image1, image2, image3, image4, image5, nil];
What you had would cause an error like this in the Xcode console:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
EDIT 26/11/13
If you have a list of images on the screen and want to check programatically if they are loaded with images, I would suggest using an array of UIImageViews instead of an array of UIImages. Then,
// Initialise the 5 UIImageViews with the UIImages that you already initialised.
UIImageView *image1 = [[UIImageView alloc] initWithImage:image1];
UIImageView *image2 = [[UIImageView alloc] initWithImage:image2];
..
..
UIImageView *image5 = [[UIImageView alloc] initWithImage:image1];
// Put all the UIImageViews in an array.
_imageArray = [[NSArray alloc] initWithObjects:image1, image2, image3, image4, image5, nil];
// Make this method to count the number of images in the given array.
- (int)numberOfImagesIn:(NSArray *)array {
int count = 0;
for (UIImageView *view in array) {
if (view.image) {
count++;
}
}
return count;
}

UIScrollView Memory-Allocation and Release

I am working on a pretty simple and straightforward app that uses a couple of pages with scroll views. I have an array of images in ViewDidLoad and then a mutable array that shows current page plus and minus 1. There is a purge page method which is supposed to remove the extra images from the superview. When running this on an actual device with a large quantity of images, a memory warning comes up after scrolling through 50 or so images and then the app crashes. I ran this through instruments and see that the memory in increasing substantially with each swipe. When creating the array I used imageNamed as well as imageWithContentsOfFile and either way gives close to the same result. I realize there have been multiple scrollview questions here, but somehow I cannot seem to get past this one. Frustrating to say the least. I hope someone can look at this with a fresh set of eyes and shed some light on my problem. Thanks very much in advance.
EDIT: Forgot to mention ARC use. Yes, I use ARC.
Code: .h file
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <UIScrollViewDelegate>
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
#end
and the .m file
#import "FirstViewController.h"
#interface FirstViewController ()
#property (nonatomic, strong) NSArray *pageImages;
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
#implementation FirstViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)loadVisiblePages {
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages you want to load
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
// Load pages in our range
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
// Purge anything after the last page
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (void)purgePage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
// If it's outside the range of what you have to display, then do nothing
return;
}
// Remove a page from the scroll view and reset the container array
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null]) {
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
// If it's outside the range of what you have to display, then do nothing
return;
}
// 1
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
// 2
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
// 3
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = frame;
[self.scrollView addSubview:newPageView];
// 4
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Load the pages that are now on screen
[self loadVisiblePages];
}
- (void)viewDidLoad {
[super viewDidLoad];
// 1
self.pageImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"BBD1.jpg"],
[UIImage imageNamed:#"BBD2.jpg"],
[UIImage imageNamed:#"BBD3.jpg"],
[UIImage imageNamed:#"BBD4.jpg"],
[UIImage imageNamed:#"BBD5.jpg"],
[UIImage imageNamed:#"BBD6.jpg"],
[UIImage imageNamed:#"BBD7.jpg"],
.....
[UIImage imageNamed:#"BBD292.jpg"],
[UIImage imageNamed:#"BBD293.jpg"],
[UIImage imageNamed:#"BBD294.jpg"],
[UIImage imageNamed:#"BBD295.jpg"],
[UIImage imageNamed:#"BBD296.jpg"],
[UIImage imageNamed:#"BBD297.jpg"],
[UIImage imageNamed:#"BBD298.jpg"],
[UIImage imageNamed:#"BBD299.jpg"],
[UIImage imageNamed:#"BBD300.jpg"],
nil];
NSInteger pageCount = self.pageImages.count;
// 2
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
// 3
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i) {
[self.pageViews addObject:[NSNull null]];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 4
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
// 5
[self loadVisiblePages];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#end
I really appreciate you taking the time to look at this and hope there is someone out there who can point me in the right direction.
THANKS!
Loading the actual images into the array incurs a much larger overhead than storing just the names in the array and loading the image like
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self.pageImages objectAtIndex:page]];
UIImageView *newPageView = [[UIImageView alloc] initWithImage:image];
[image release];
At this point, only the newPageView will hold a reference to the image in memory, and when that newPageView is removed from it's superview, the image in memory will be released.
You don't say if you are using ARC or not, but without ARC there are obvious problems in memory management. In loadPage: at comment "// 3" you create newPageView with a retain count of 1, then add it as a subview of self.scrollView and to the array self.pageViews. Thus it has an overall retain count of +3. In purgePage: you remove it from self.scrollView and self.pageViews but are still left with an overall retain count of +1. Thus the UIImageView for each page is forgotten but not deallocated.
You can fix this by using ARC in your project or modifying the line where you create newPageView to be instead:
UIImageView *newPageView = [[[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]] autorelease];

Retaining array in subclass

Updated:
I have subclassed UIImageView to make some images movable through touch gestures. In the view controller I have an array holding the initial position of each imageview. My problem is that this array returns null whenever it is called on from the subclass. The idea is to check if the image is in its original position or if it has already been moved before, I have stripped the code to just NSLog what's going on but the problem remains and is driving me nuts.
ViewController.h
NSMutableArray *originalPositions;
#property (nonatomic, retain) NSMutableArray *originalPositions;
-(void)testLogging;
ViewController.m
#synthesize originalPositions;
- (void)viewDidLoad {
originalPositions = [[NSMutableArray alloc]init];
}
-(void)drawImages {
for (int i = 0; i < imagesArray.count; i++) {
CGRect frame = CGRectMake(65 * i, 10, 60, 60);
draggableView *dragImage = [[draggableView alloc] initWithFrame:frame];
NSString* imgName = [imagesArray objectAtIndex:i];
[dragImage setImage:[UIImage imageNamed:imgName]];
[dragImage setUserInteractionEnabled:YES];
[self.view addSubview:dragImage];
NSString *originalPositionAsString = NSStringFromCGPoint(dragImage.center);
[originalPositions addObject:originalPositionAsString];
}
}
-(void)testLogging {
NSLog(#"Logging array: %#", originalPositions);
}
-(IBAction)btnClicked {
[self testLogging];
}
When called from the IBAction (or any other way) in the class, the 'testLogging'-method NSLogs the array correctly but if I call the same method from the subclass, it NSLogs null:
Subclass.m
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
ViewController *viewController = [[ViewController alloc] init];
[viewController testLogging];
}
self.originalPositions = [[NSMutableArray alloc]init];
This already is a memory leak, when you call self.originalPositions = bla then 'bla' will be retained. Thus meaning that the retain count is upped. This means that your mutable array will have a retain count of 2 and that it will leak once your UIImageView is gone.
As for the rest, I wouldn't know what is wrong with your code. My first guess would be that you didn't call populatePositionsArray yet, you should call this whenever your view is created / shown so you are sure the array is populated when touchesBegan is called.
Alternatively you could include an 'if' statement in the touchesBegan that checks whether the array exists and otherwise call the populatePositionsArray to populate it before continueing.
I solved it by writing the array to a plist file after populating it. Not very elegant but working.
Thanks for the help though guys.

contacts data in xcode

Everybody..
I am trying to develop an app for iPhone which basicly deals with ABAddressBook and contacts data...
My goal is to send all the contacts data (at first step, names and phones) in a file by e-mail..
Now, I am trying to reach the contacts data, and I want to add them to two different arrays, names and phones arrays..
At first, I am trying to see all the datas in the screen when i pressed a button "List Contacts". the datas should be seen on the screen. and then when i pressed the second button "Send Contacts", it should send the file to an e-mail account.. This is how my apps will work..
I am having problems at showing the data on the screen.. I wrote something but it doesn't give anything on the screen in a textView..
Can you help me to solve this problem?
Here's the code for listing the contacts (listCon method):
-(IBAction)listCon:(id)sender
{
NSMutableArray *names = [[NSMutableArray alloc] init];
NSMutableArray *numbers1= [[NSMutableArray array] init];
NSMutableArray *numbers2= [[NSMutableArray array] init];
NSMutableArray *numbers3= [[NSMutableArray array] init];
ABAddressBookRef addressBook = ABAddressBookCreate();
if (addressBook != nil)
{
NSLog(#"Successfully accessed the address book.");
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople= ABAddressBookGetPersonCount(addressBook);
NSUInteger peopleCounter = 0;
for (peopleCounter = 0;peopleCounter < nPeople; peopleCounter++)
{
ABRecordRef thisPerson = CFArrayGetValueAtIndex(allPeople,peopleCounter);
NSString *contactFirstLast = [NSString stringWithFormat:#"%,%",ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty), ABRecordCopyValue(thisPerson,kABPersonLastNameProperty)];
[names insertObject:contactFirstLast atIndex:peopleCounter];
ABMultiValueRef phoneNumbers = ABRecordCopyValue(thisPerson,kABPersonPhoneProperty);
NSString *firstPhone = (__bridge_transfer NSString*) ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
NSString *secondPhone = (__bridge_transfer NSString*) ABMultiValueCopyValueAtIndex(phoneNumbers, 1);
NSString *thirdPhone = (__bridge_transfer NSString*) ABMultiValueCopyValueAtIndex(phoneNumbers, 2);
[numbers1 insertObject:firstPhone atIndex:peopleCounter];
[numbers2 insertObject:secondPhone atIndex:peopleCounter];
[numbers3 insertObject:thirdPhone atIndex:peopleCounter];
}
}
myView.text=[names componentsJoinedByString:#"\n\n"];
myView.text=[numbers1 componentsJoinedByString:#"\n\n"];
myView.text=[numbers2 componentsJoinedByString:#"\n\n"];
myView.text=[numbers3 componentsJoinedByString:#"\n\n"];
}
Just glancing at your code, you can't do this:
NSString *contactFirstLast = [NSString stringWithFormat:#"%,%",ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty), ABRecordCopyValue(thisPerson,kABPersonLastNameProperty)];
There are several errors: first off % in your stringWithFormat: is not a format specifier; you probably are thinking of %#. Second off, copying the value of kABPersonFirstNameProperty will return a CFStringRef, and that's not what you want to display the name in a text field. You'll have to toll-free bridge the result of ABRecordCopyValue(). You can do this by adding this line - (__bridge_transfer NSString *) - in front of your ABRecordCopyValue()'s. With all the corrections, it should look like this:
NSString *contactFirstLast = [NSString stringWithFormat:#"%#,%#", (__bridge_transfer NSString *)ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty), (__bridge_transfer NSString *)ABRecordCopyValue(thisPerson,kABPersonLastNameProperty)];
Hope this help (might not cover all errors)!

Xcode : Wallpapers with UIButton

I want to make an wallpaper iphone app.
Now if i have for example 100 wallpapers , do I have to create 100 nib files and 100 .m and .h files and 100 UIButtons for to save the wallpaper and 100 UIButton for to go to the previous or next wallpaper ?
Is there any other way to do this ?
Thanks !
yes sure.
save your hundred wallpapers in the resources folder. The are named like this "wp_1.png", "wp_2.png" etc.
Then you create a nib with the buttons (previous, next and save)
In the uiviewcontroller you'll have an int property. For instance you call it n or something like that. I would suggest adding another property for your wallpaper (UIImageView) Then you implement the methods in the view controller.
-(void)awakeFromNib {
self.n = 1;
UIImage* wallpaper = [UIImage imageNamed:#"wp_1.png"];
UIImageView* view = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
self.wallpaper = view;
view.image=wallpaper;
[self.view addSubview:view];
}
-(IBAction)next:(id)sender {
self.n++; // increases n by 1;
[self.wallpaper removeFromSuperview];
NSString* name = [NSString stringWithFormat:#"wp_%i.png", self.n];
UIImage* wallpaper = [UIImage imageNamed:name];
UIImageView* view = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
self.wallpaper = view;
view.image=wallpaper;
[self.view addSubview:view];
}
something like that. hope that helps
Of course not. I would use a UITableView for that. Or even better a custom view that looks similar to the Photos app on the iphone.
You don't want to use a UIButton to go to the previous or next photo. You want to use a UIScrollView in paging mode.
But you don't want the user to browse through your images in that way in the first place.
Create a index screen that has a UIScrollView (non-paging this time) with thumbnails of all your images. And when one is tapped it zooms in with a nice animation and you can flick to the next or previous image with the paging UIScrollView I mentioned earlier.
You know, like the Photos app.
in the header (.h file) add something like that:
int n;
UIImageView* wallpaper;
}
#property (readwrite) int n;
#property (readwrite, retain) UIImageView* wallpaper;
in the implemention fil (.m file) :
#synthesize n, wallpaper;

Resources