I've seen a lot of feature wishes, but one I have not seen that would be really useful. That would be backup over Wi-Fi. But more precisely, give me the option to backup when I plug in the charger.
My phone rarely gets backed up because I'm not in front of my Mac every day (it sits in the basement.) I typically use my iPhone or netbook upstairs for daily use. I do however, charge my iPhone every night.
Backups over Wi-Fi would be a battery drainer, so it would be preferable to happen while plugged in. Therefore when I plug in the charger, it could pop up an option to backup the phone over Wi-Fi. Then the phone gets backed up and synced every night, without the hassle of visiting the dock.
Tuesday, January 26, 2010
Sunday, January 24, 2010
Cocoa and Delegates
Delegates are probably one of the toughest concepts for iPhone/OSX developer newcomers to grasp. I'm going to try to keep it simple, and demonstrate how to build your own delegate protocol into your classes.
A delegate is merely a design pattern in Objective-C. Simply put, it provides a way for objects to "listen" for interesting things happening in your object and act on them without your object knowing anything about the object(s) listening. Delegates are used heavily in the Cocoa environment. Most often you will see delegates used to trigger methods on a UIViewController, although they can be implemented on anything.
Let's think for a moment what type of problem this solves. Let's say we have a UIViewController which has a UITableView in its view. When a table row is tapped, we want to slide a new view onto the screen. We don't want UITableView handling this task, so how do we accomplish this?
The UIViewController needs to handle the new view (thus it's name.) So the UITableView needs to somehow inform the UIViewController that a row was tapped so it can take action. Therefore, the UIViewController needs to be the delegate of the UITableView. So we need to setup two things: We need to inform the UITableView what it's delegate object is, and we need to inform the delegate object what delegate protocol(s) it conforms to.
We begin by setting the delegate property of the UITableView to the UIViewController object. If you are using Interface Builder, you can simply connect the delegate property of the UITableView to the UIViewController (typically the File's Owner.) Otherwise you might handle this in the viewDidLoad{} of the UIViewController, something like:
You will also want to tell the view controller that it understands the UITableViewDelegate protocol, so you would put this in the UIViewController .h interface declaration:
And you are set! Now when you implement a method of the UITableViewDelegate in the UIViewController, this method will trigger when something happens in the table view for that delegate method. So for instance, you put this in your UIViewController .m file:
So now begs the question, how do you add your own delegate protocol to your custom classes? Here is an example. Let's say you want to be able to trigger methods of other classes when interesting things happen in your class. The first thing you need to do is define what delegate methods are available to the delegate object. You would first put something like this at the top of your class .h file, above the implementation declaration:
Where MyCustomClassDelegate is the name of your class delegate protocol (your class name appended with "Delegate"), and didClickDone and didClickCancel are the names of your two delegate methods. You can add as many methods as you wish. You not need to implement these methods in your class, that is up to the delegate to do. Notice the line with @optional. This means that the following methods are optional for the delegate to implement.
Now we need to setup the delegate property:
And finally in the .m file, synthesize the delegate:
Note we do not need to release the delegate in the dealloc method, as this is not a retained object, it is just an assigned id.
Ok, for the final part of your class, you need to fire off the delegate method when something interesting happens. For instance, someone clicks the done button. In your IBAction for the done button, you do just that:
And so on, for each delegate method. Ok, that is it for the class. Now, for the delegate class. To be the delegate of MyCustomClass, you need to declare that you implement the MyCustomClassDelegate protocol (.h file):
And then, we implement the delegate methods (.m file):
One last thing to note, a class can be the delegate for several objects, just comma-separate the delegates:
I hope that helps clear up delegates a bit! Please leave your comments below.
A delegate is merely a design pattern in Objective-C. Simply put, it provides a way for objects to "listen" for interesting things happening in your object and act on them without your object knowing anything about the object(s) listening. Delegates are used heavily in the Cocoa environment. Most often you will see delegates used to trigger methods on a UIViewController, although they can be implemented on anything.
Let's think for a moment what type of problem this solves. Let's say we have a UIViewController which has a UITableView in its view. When a table row is tapped, we want to slide a new view onto the screen. We don't want UITableView handling this task, so how do we accomplish this?
The UIViewController needs to handle the new view (thus it's name.) So the UITableView needs to somehow inform the UIViewController that a row was tapped so it can take action. Therefore, the UIViewController needs to be the delegate of the UITableView. So we need to setup two things: We need to inform the UITableView what it's delegate object is, and we need to inform the delegate object what delegate protocol(s) it conforms to.
We begin by setting the delegate property of the UITableView to the UIViewController object. If you are using Interface Builder, you can simply connect the delegate property of the UITableView to the UIViewController (typically the File's Owner.) Otherwise you might handle this in the viewDidLoad{} of the UIViewController, something like:
self.tableView.delegate = self;
You will also want to tell the view controller that it understands the UITableViewDelegate protocol, so you would put this in the UIViewController .h interface declaration:
@interface MyViewController : UIViewController(Note: if your view controller is an extension of UITableViewController, you will not need to declare the UITableViewDelegate protocol.)
<UITableViewDelegate> {}
And you are set! Now when you implement a method of the UITableViewDelegate in the UIViewController, this method will trigger when something happens in the table view for that delegate method. So for instance, you put this in your UIViewController .m file:
When a row is selected in the table, this method will get triggered.
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// push the new view onto the stack here
}
So now begs the question, how do you add your own delegate protocol to your custom classes? Here is an example. Let's say you want to be able to trigger methods of other classes when interesting things happen in your class. The first thing you need to do is define what delegate methods are available to the delegate object. You would first put something like this at the top of your class .h file, above the implementation declaration:
@protocol MyCustomClassDelegate <NSObject>;
- (void)didClickDone:(UIButton *)button;
@optional
-(void)didClickCancel:(UIButton *)button;
@end
Where MyCustomClassDelegate is the name of your class delegate protocol (your class name appended with "Delegate"), and didClickDone and didClickCancel are the names of your two delegate methods. You can add as many methods as you wish. You not need to implement these methods in your class, that is up to the delegate to do. Notice the line with @optional. This means that the following methods are optional for the delegate to implement.
Now we need to setup the delegate property:
@interface MyCustomClass : NSObject {
id <MyCustomClassDelegate> delegate;
}
@property (nonatomic, assign)
id <MyCustomClassDelegate> delegate;
And finally in the .m file, synthesize the delegate:
@synthesize delegate;
Note we do not need to release the delegate in the dealloc method, as this is not a retained object, it is just an assigned id.
Ok, for the final part of your class, you need to fire off the delegate method when something interesting happens. For instance, someone clicks the done button. In your IBAction for the done button, you do just that:
-(IBAction)done:(UIButton *)button {
[self.delegate didClickDone:button];
}
And so on, for each delegate method. Ok, that is it for the class. Now, for the delegate class. To be the delegate of MyCustomClass, you need to declare that you implement the MyCustomClassDelegate protocol (.h file):
@interface MyViewController:
UIViewController <MyCustomClassDelegate> { }
And then, we implement the delegate methods (.m file):
-(void)didClickDone:(UIButton *)button {
// do something here!
}
One last thing to note, a class can be the delegate for several objects, just comma-separate the delegates:
@interface MyViewController:
UIViewController <MyCustomClassDelegate,SomeOtherDelegate> { }
I hope that helps clear up delegates a bit! Please leave your comments below.
Saturday, January 2, 2010
Winning one million from the casino, guaranteed (nearly)
So you want to beat the casino for a cool million. Ok, here is a system on the roulette table. It's theoretical, it will take awhile, and you had better have some deep pockets. Here is how it works.
1) bet $1 on red (or black, whatever you prefer)
2) if you lose, bet $2 on red/black
3) if you lose, bet $4 on red/black
... continue this pattern until you win...
4) you win $1. Start over on step 1.
Continue the above step system 1,000,000 times. At the end, you should end up $1,000,000 ahead. Now there is a couple of things to consider. Although it is highly unlikely you will win/lose more than, say, 20 times in a row, it is quite possible to happen in 1,000,000 runs of the above system. In that case, you could be wagering a lot once in a while. In a computer simulation of running the system 1000 times, There was a bet of 134 million touched. That's quite a bit to hope for a dollar.
So to be able to run this system, you have to have DEEP pockets. That, and find a casino that will let you play this way. Good luck with that :)
From the simulation, here is the breakdown of wagers, # of times encountered, and % chances of happening:
1) bet $1 on red (or black, whatever you prefer)
2) if you lose, bet $2 on red/black
3) if you lose, bet $4 on red/black
... continue this pattern until you win...
4) you win $1. Start over on step 1.
Continue the above step system 1,000,000 times. At the end, you should end up $1,000,000 ahead. Now there is a couple of things to consider. Although it is highly unlikely you will win/lose more than, say, 20 times in a row, it is quite possible to happen in 1,000,000 runs of the above system. In that case, you could be wagering a lot once in a while. In a computer simulation of running the system 1000 times, There was a bet of 134 million touched. That's quite a bit to hope for a dollar.
So to be able to run this system, you have to have DEEP pockets. That, and find a casino that will let you play this way. Good luck with that :)
From the simulation, here is the breakdown of wagers, # of times encountered, and % chances of happening:
wager: $1 # of times: 47363291 (47.363291000%)
wager: $2 # of times: 24927507 (24.927507000%)
wager: $4 # of times: 13121947 (13.121947000%)
wager: $8 # of times: 6908653 (6.908653000%)
wager: $16 # of times: 3637176 (3.637176000%)
wager: $32 # of times: 1915725 (1.915725000%)
wager: $64 # of times: 1007786 (1.007786000%)
wager: $128 # of times: 528916 (0.528916000%)
wager: $256 # of times: 278835 (0.278835000%)
wager: $512 # of times: 147026 (0.147026000%)
wager: $1024 # of times: 77406 (0.077406000%)
wager: $2048 # of times: 40696 (0.040696000%)
wager: $4096 # of times: 21300 (0.021300000%)
wager: $8192 # of times: 11167 (0.011167000%)
wager: $16384 # of times: 5988 (0.005988000%)
wager: $32768 # of times: 3215 (0.003215000%)
wager: $65536 # of times: 1609 (0.001609000%)
wager: $131072 # of times: 840 (0.000840000%)
wager: $262144 # of times: 417 (0.000417000%)
wager: $524288 # of times: 246 (0.000246000%)
wager: $1048576 # of times: 126 (0.000126000%)
wager: $2097152 # of times: 67 (0.000067000%)
wager: $4194304 # of times: 35 (0.000035000%)
wager: $8388608 # of times: 13 (0.000013000%)
wager: $16777216 # of times: 7 (0.000007000%)
wager: $33554432 # of times: 6 (0.000006000%)
wager: $67108864 # of times: 4 (0.000004000%)
wager: $134217728 # of times: 1 (0.000001000%)
Thursday, December 17, 2009
What will happen in 2110?
Here is a very interesting article posting predictions for year 2000 made in 1900. Many predictions were quite good!
http://bunchofnerds.com/2008/10/retro/predictions-for-the-year-2000-from-the-year-1900/
So lets start a new prediction thread. What do YOU think the world will consist of in 2110? Comments will be open until the end of 2010.
http://bunchofnerds.com/2008/10/retro/predictions-for-the-year-2000-from-the-year-1900/
So lets start a new prediction thread. What do YOU think the world will consist of in 2110? Comments will be open until the end of 2010.
Thursday, November 12, 2009
AJAX and PHP sessions
One thing that trips up AJAX development is how to persist your PHP session through your AJAX calls. In a browser, the session persists through a cookie that passes the session id upon each request. However with an AJAX call, the browser cookies are not passed and the session is lost.
There are a couple of easy ways around this. First, if your AJAX library supports cookies, you can just set the PHP session id cookie before the call. If you don't have cookie support, then the following "manual" method works quite well.
What you will want to do is pass the session id as a POST or GET variable in your AJAX request. We'll call our variable name "sid".
Here is a jQuery example for passing the sid through as a POST value (in a PHP script):
This will POST the current session id through the form. Next on the PHP side, you must set the session id with this posted value:
As for security, be aware that you don't have the same restrictions that come with cookies (domain, date, etc.) so once you pass the session id to javascript, be careful what can be manipulated through javascript code. It's pretty much the same as being aware of javascript getting/setting cookie values themselves.
Hope that helps!
There are a couple of easy ways around this. First, if your AJAX library supports cookies, you can just set the PHP session id cookie before the call. If you don't have cookie support, then the following "manual" method works quite well.
What you will want to do is pass the session id as a POST or GET variable in your AJAX request. We'll call our variable name "sid".
Here is a jQuery example for passing the sid through as a POST value (in a PHP script):
$.post("test.php", { sid: "<?php echo session_id(); ?>" } );
This will POST the current session id through the form. Next on the PHP side, you must set the session id with this posted value:
<?php
// set session to value from ajax post
session_id($_POST['sid']);
// we now have $_SESSION data!
?>
As for security, be aware that you don't have the same restrictions that come with cookies (domain, date, etc.) so once you pass the session id to javascript, be careful what can be manipulated through javascript code. It's pretty much the same as being aware of javascript getting/setting cookie values themselves.
Hope that helps!
Saturday, October 24, 2009
Being a winning online poker player
You know you are capable of playing great poker, but you continuously lose your bankroll playing online poker. How do you get over this hurdle? What is the secret? There are two important factors.
Factor 1: Don't play on tilt
Winning poker is not about focusing on how much you've won or lost. It's how you handle losing. How often do you get bad beat, then jump right back in and lose more and more? How often do you make a big win, only to lose it all over the course of days or weeks?
So to overcome factor 1: If you get a bad beat or get on a losing streak, force yourself to take a break before playing again. How long or what this is depends on what it takes to get your mind free of the past. Maybe it's a nap. Maybe it's a walk around the house. Maybe it's a jog around the block. The important element is that you are not playing the next game with the predisposition of steaming. Get over it first, then continue playing.
Factor 2: Bankroll management
Losing is a fact of the game, it will happen. To stay alive, you must manage your bankroll. This sounds easy, but it can take a considerable amount of discipline. If you don't want to buy in again, you *must* manage your bankroll, no matter how good you are. A rule of thumb for sit-and-goes and MTTs: Take the buy-in multiplied by # of players. If that amount is greater than your bankroll, move down.
If you get on a losing streak, just stick to the plan. Take a break, and move down in stakes until you can recover.
Follow these rules, and the only way you can lose is by playing bad poker. Hopefully you've gotten past that part :) Good Luck!
Factor 1: Don't play on tilt
Winning poker is not about focusing on how much you've won or lost. It's how you handle losing. How often do you get bad beat, then jump right back in and lose more and more? How often do you make a big win, only to lose it all over the course of days or weeks?
So to overcome factor 1: If you get a bad beat or get on a losing streak, force yourself to take a break before playing again. How long or what this is depends on what it takes to get your mind free of the past. Maybe it's a nap. Maybe it's a walk around the house. Maybe it's a jog around the block. The important element is that you are not playing the next game with the predisposition of steaming. Get over it first, then continue playing.
Factor 2: Bankroll management
Losing is a fact of the game, it will happen. To stay alive, you must manage your bankroll. This sounds easy, but it can take a considerable amount of discipline. If you don't want to buy in again, you *must* manage your bankroll, no matter how good you are. A rule of thumb for sit-and-goes and MTTs: Take the buy-in multiplied by # of players. If that amount is greater than your bankroll, move down.
If you get on a losing streak, just stick to the plan. Take a break, and move down in stakes until you can recover.
Follow these rules, and the only way you can lose is by playing bad poker. Hopefully you've gotten past that part :) Good Luck!
Sunday, August 9, 2009
Basecamp PHP API
I needed a complete PHP class for the Basecamp API with a project I'm working on at REBEL. Finding nothing that would fit the bill, I wrote one.
http://code.google.com/p/basecamp-php-api/
http://code.google.com/p/basecamp-php-api/
Subscribe to:
Posts (Atom)