Jul 15

Some time ago I commented how to detect changes in properties using KVO (Key-Value Observing), today we will see how to do the same using notifications.

The idea from the example is the following: We have an object A from a X class, we want to be notified when a property of A is changed, to be so, we will notify another object B, so B can do some stuff. We are going to do this with notifications, the object A will send a notification when it changes it’s property and the object B will be looking for this notifications.

Lets see what do we need to do in the code for that, first we create a function which will send the notification. We are going to use the default notification center for our application and the method postNotificationName:object: to send the notification. The parameters are a string for the name of the notification and the object sending he notification.

#pragma mark -
#pragma mark Notification methods
 
- (void)sendNumberPadPressedNotification {
     [[NSNotificationCenter defaultCenter] postNotificationName:@"number pad pressed" 
                                                         object:self];
}

Next we only need to call this function every time we want to notify of the change or event, for example if a button is pressed.

#pragma mark -
#pragma mark Notification methods
- (IBAction)ceroButtonPushed:(id)sender {
     [input setString:[numberFormater stringFromNumber:[NSNumber numberWithFloat:0.00]]];
     coma = NO;
     decimal = 1;
     [self sendNumberPadPressedNotification];
}

Notice we call our method in the last line, in this example the notification is used to let know of the changes in input.

This is all we need to do for object A (the one sending the notification). Lets se now the code for the object B (the one looking for the changes).

First we have to register B in the notification center to be able to get them, we need to use the same notification center as in A, in this case the default one.

We use the method addObserver:selector:name:object:, the parameters are: the object to be registered, a selector to the method to call after getting the notification, the name of the notification we register for and the object we want to be notified for, this last one can be nil or the same object sending the notification, in case we have more than one object sending the same notification and we want to know who sent it.

 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
 - (void)viewDidLoad {
     [super viewDidLoad];
     numberPadController = [[GenericNumberPad alloc] initWithNibName:@"GenericNumberPad"
     	  						      bundle:[NSBundle mainBundle]
							       frame:CGRectMake(20, 190, 280, 216)];
     [[NSNotificationCenter defaultCenter] addObserver:self 
                                              selector:@selector(numberPadPressed)
						  name:@"number pad pressed" object:nil];
     [[self view] addSubview:[numberPadController view]];
 }

As you can see in the code, the name of the notification is the same as the one we use in object A. Now we only need to do some stuff in the function we gave.

#pragma mark -
#pragma mark Notification methods
 
- (void)numberPadPressed {
     [importLabel setText:[numberPadController input]];
}

In this example we use the notifications to refresh a label with the value of the variable input each time it’s value changed.

VN:F [1.9.8_1114]
Rating: 5.0/5 (1 vote cast)
VN:F [1.9.8_1114]
Rating: 0 (from 0 votes)
Tagged with:
Jul 05

In this post we will see how to get files that our application creates during runtime, this can be useful when we need to check that the files is being build properly or when we want to save the database build from the app.

To do it we will use Xcode from the window organizer, you can open it from the view menu. In the organizer and with your iPhone plug in, we will have access to our applications folders. Find your application and click in the triangle to see its content.

Now we should be seeing the common package icon.

Now, we only need to drag the icon to the desktop and we will get a folder with the content of the folders Documents, Library and tmp from our application.

With this and the earlier post, we can access to any file created during runtime of oir applications.

Other important thing to know is that if we do any changes in this folder and drag it back to the application in the organizer window we will be able to put in our application sandbox any file to use it in runtime.

VN:F [1.9.8_1114]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.8_1114]
Rating: 0 (from 0 votes)
Tagged with:
Jul 05

With this post I will show how to copy a file added to our project to the documents folder of our application. The idea is to be able to initialize in a fast and easy way the database, some configuration files or any similar file that we must save in the documents folder because it will be change by the user during runtime. That way we don’t have to create them from the code.

First, we need to add the file to our project, add it to the “Resources” folder of your project so it is accessible from the code of your application.

Once we have the file in the project, we can add the code to copy the file to the documents folder, add the next code to your AppDelegate, you can create a new method for initialization purpose or add it directly to the AppDelegate init.

// Copy init.sqlite from resources to the Documents folder in bundle
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"data.sqlite"];
if(![[NSFileManager defaultManager] fileExistsAtPath:storePath])
{
	NSString *filePath = [[NSBundle mainBundle] pathForResource:@"init" ofType:@"sqlite"];
	NSData *myData = [NSData dataWithContentsOfFile:filePath];
	if (![myData writeToFile:storePath atomically:YES]) {
		NSLog(@"ERROR writting the starting database");
	}
}

In the code we use a file, init.sqlite, as an initial database for our application and we save the same file under the name data.sqlite in the documents folder of our application. Notice that we use an if to check if that file already exists, that way this code will only be executed the first time we launch our application, this is so we don’t delete any new data the user may have introduced. If during your testing you want to get the initial database again, delete the application from your iPhone or from the iPhone Simulator.

The method applicationDocumentsDirectory is the following function, returning the path to the documents folder.

/**
 Returns the path to the application's Documents directory.
 */
- (NSString *)applicationDocumentsDirectory {
	return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
VN:F [1.9.8_1114]
Rating: 5.0/5 (1 vote cast)
VN:F [1.9.8_1114]
Rating: +1 (from 1 vote)
Tagged with:
Jun 13

When we work with table (UITableView), we can build custom cells with Interface Builder and load them, o build them directly from the code. The problem appears when we change the background color for the custom cell, but don’t do the same when there are empty cells on screen.

We can see something like this.

This happens cause we only make the cells while we have data but may be more cells in screen than data to show. We have two solutions:

  • Prepare our code to take into account both cases, changing the background color when there is no data but put away any other element of the custom cell.
  • Change the background color in all cells, before we take into account anything else.

With the second solution it’s faster, we need to do this in code, as Interface Builder doesn’t let us get to where we need only adding a table.

We need to add only a line to our code

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    static NSString *CellIdentifier = @"Cell";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
 
    // Configure the cell.
    [[cell contentView] setBackgroundColor:[UIColor colorWithRed:0 green:128/255.f blue:0 alpha:1]];
    return cell;
}

The important line is the one where we call the method setBackgroundColor:, with this line we change the color but notice that we change the background color for [cell contentView], we have to change the contentView and this is way we can’t do this from Interface Builder, it won’t let us change the background of the cells, only the background of the table view.

We get now something like this

VN:F [1.9.8_1114]
Rating: 5.0/5 (2 votes cast)
VN:F [1.9.8_1114]
Rating: +1 (from 1 vote)
Tagged with:
Jun 13

I don’t know if it has ever happend to you that to clean your iPhone Simulator instead of deleting app by app, you did a reset and found out that all pictures had dissapeared XD, what did you expect ;).

Well, if you did a reset willingly, by error or to clean all the apps and data that is created while you test and test your apps, here there are a couple of tricks to add new pictures:

Photos we have on files:

To add pictures from your own files you only have to copy them into:

~/Users/<usuario>/Library/Application Support/iPhone Simulator/3.1.3/Media/DCIM/100APPLE

Where <usuario> is your user name, and maybe you have to change too the SDK version you are working with.

Note: I have seen different routes around internet, the idea is that you have to be in the iPhone Simulator folder ~/Library/Application Support/iPhone Simulator/… and add the images to Media/DCIM/100APPLE, i this last folder doesn’t exist you must create it.

Variant: You can also open Safari in your simulator and drag file by file to the webpage, then hold left click on the image till you  get the option to save it. It will be added to your library.

Pictures from internet:

In case you want to add new images from internet, for example google images, you only need to do as before, click and hold on the image you want to safe in Safari to get the option to save it.

VN:F [1.9.8_1114]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.8_1114]
Rating: 0 (from 0 votes)
Tagged with:
preload preload preload