jueves, 18 de noviembre de 2010
Avoid uploading duplicated files in FTP using MSDOS script
jueves, 11 de noviembre de 2010
FTP Uploading files using MSDOS script
viernes, 27 de agosto de 2010
Daily accomplishments
viernes, 13 de agosto de 2010
iPhone's Numeric Pad keyboard with a DOT
IBOutlet UITextField * textMoney;
self.textMoney.keyboardType = UIKeyboardTypeNumberPad;
/**
View will appear
**/
- (void)viewWillAppear:(BOOL)animtated
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}
else
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
}
/**
View will disappear
**/
- (void)viewWillDisappear:(BOOL)animtated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
/**
The Keyboard will be shown
**/
- (void)keyboardWillShow:(NSNotification *)notification
{
if ([textNotes isFirstResponder])
{
// Skip for Notes keyboard
return;
}
// Locate fist view
UIWindow *tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView *keyboard;
// Define Button
UIButton * utilityButton = [UIButton buttonWithType:UIButtonTypeCustom];
utilityButton.frame = CGRectMake(0, 163, 105, 53);
// Set Text and font
[utilityButton.titleLabel setFont:[UIFont systemFontOfSize:35]];
[utilityButton setTitle:[Dot or Comma according with localized settings] forState:UIControlStateNormal];
// Set Solors
[utilityButton setTitleColor:[UIColor colorWithRed:77.0f/255.0f green:84.0f/255.0f blue:98.0f/255.0f alpha:1.0] forState:UIControlStateNormal];
[utilityButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
// Background for the pressed state
[utilityButton setBackgroundImage:[UIImage imageNamed:@"background.png"] forState:UIControlStateHighlighted];
// Add call to functionality
[utilityButton addTarget:self action:@selector(addDecimalPointToField) forControlEvents:UIControlEventTouchUpInside];
// Behavior when orientation is changed
[utilityButton setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight)];
// Locate keyboard view and add button
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2)
{
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
{
[keyboard addSubview:utilityButton];
}
}
else
{
if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
{
[keyboard addSubview:utilityButton];
}
}
}
}
/**
Send Decimal Point event to field with focus
**/
- (void)addDecimalPointToField
{
UIView * objectToEdit = nil;
// Locate field with the focus
for (UIView * localView in self.scrollView.subviews)
{
if ([localView isFirstResponder])
{
objectToEdit = localView;
}
}
// Try to insert dot
if (objectToEdit != nil)
{
// Detect if the Dot has been already inserted
NSString * localText = [(UITextField *)objectToEdit text];
NSRange separatorPosition = [localText rangeOfString:[Dot or Comma according with localized settings]];
if (separatorPosition.location == NSNotFound)
{
// Dot wasn't found, add it
[objectToEdit insertText:[NSString stringWithFormat:[Dot or Comma according with localized settings]]];
}
}
}
lunes, 2 de agosto de 2010
Migrating Contacts over phones
jueves, 8 de julio de 2010
WebServices solution for iPhone - Second Stage
- The FileDownloadController class will create and manage all needed FileDownload objects
- Whenever an object needs to download a file, it should get the FileDownloadController instance and then asks for the download
- Once the download is complete, or in case of error, a callback will be received by the requesting object
- Store requests in a queue and attend them once a slot is available
- Cancel the oldest download and use it for the requested
@interface FileDownloadControllerItem : NSObject
{
int jobID;
FileDownload * downloadObject;
NSDate * startTime;
}
@property (nonatomic, retain) FileDownload * downloadObject;
@property (nonatomic, assign) int jobID;
@property (nonatomic, retain) NSDate * startTime;
-(FileDownloadControllerItem *)initwithDelegate:(id)delegate;
-(void)downloadFile:(NSInteger)fileID fileName:(NSString *)name callBack:(id<FileDownloadProtocol>)delegate;
-(void)stopDownload;
@end
- jobID it holds the Download ID discussed in the previous post of this series.
- downloadObject holds the FileDownload object that will be used to process the download
- startTime holds the time when the download was called and will be used to identify the older download when a new download is requested and there are no available slots
-(FileDownloadControllerItem *)initwithDelegate:(id)delegate;
-(void)downloadFile:(NSInteger)fileID fileName:(NSString *)name callBack:(id<FileDownloadProtocol>)delegate;
-(void)stopDownload;
/**
Initializtion given a delegate
**/
-(FileDownloadControllerItem *)initwithDelegate:(id)delegate
{
[self init];
self.jobID = FREESLOT;
self.downloadObject = [[FileDownload alloc] init];
self.startTime = [NSDate dateWithTimeIntervalSince1970:0];
return self;
}
/**
Download a file
**/
-(void)downloadFile:(NSInteger)fileID fileName:(NSString *)name callBack:(id)delegate;
{
self.jobID = fileID;
self.startTime = [NSDate dateWithTimeIntervalSinceNow:0];
[self.downloadObject setJobID:fileID];
[self.downloadObject startDownloadFile:name callBack:delegate];
}
/**
Cancel current download
**/
-(void)stopDownload
{
[self.downloadObject stopDownload];
}
@interface FileDownloadController : NSObject
{
int currentDownloads;
BOOL maintainQueue;
int totalJobs;
NSMutableArray * downloadArray;
NSMutableDictionary * callBackObjects;
}
@property (nonatomic, assign) int totalJobs;
@property (nonatomic, assign) BOOL maintainQueue;
+ (FileDownloadController *)getController;
+ (FileDownloadController *)getController:(NSInteger)jobs useQueue:(BOOL)queue;
- (FileDownloadController *)initWithJobs:(NSInteger)jobs;
- (FileDownloadController *)initWithJobs:(NSInteger)jobs useQueue:(BOOL)queue;
- (BOOL)downloadFile:(NSInteger)fileID fileName:(NSString *)name callBack:(id<FileDownloadProtocol>)delegate;
- (BOOL)findJobInQueue:(NSInteger)job;
- (void)cancelDownloadFile:(NSInteger)fileID;
- (void)stopAllDownloads;
@end
- currentDownloads is used to keep track of the actual concurrent downloads
- maintainQueue is not used, yet, but it intention is to identify if a download queue is used or if the older download might be cancelled
- totalJobs maximum number of concurrent downloads
- downloadArray this array holds all the download slots
- callBackObjects is used to hold the download ids and the callback objects; this is needed because the FileDownload will call a callback within the controller, then the controller will call the requesting object
+ (FileDownloadController *)getController;
+ (FileDownloadController *)getController:(NSInteger)jobs useQueue:(BOOL)queue;
- (FileDownloadController *)initWithJobs:(NSInteger)jobs;
- (FileDownloadController *)initWithJobs:(NSInteger)jobs useQueue:(BOOL)queue;
- (BOOL)downloadFile:(NSInteger)fileID fileName:(NSString *)name callBack:(id<FileDownloadProtocol>)delegate;
- (BOOL)findJobInQueue:(NSInteger)job;
- (void)cancelDownloadFile:(NSInteger)fileID;
- (void)stopAllDownloads;
/**
Get Singleton object
**/
+ (FileDownloadController *)getController
{
if (controller == nil)
{
controller = [[FileDownloadController alloc] initWithJobs:10 useQueue:NO];
}
return controller;
}
/**
Get Singleton object
**/
+ (FileDownloadController *)getController:(NSInteger)jobs useQueue:(BOOL)queue
{
if (controller == nil)
{
controller = [[FileDownloadController alloc] initWithJobs:jobs useQueue:queue];
}
return controller;
}
/**
Initialization with job number
**/
-(FileDownloadController *)initWithJobs:(NSInteger)jobs
{
return [self initWithJobs:jobs useQueue:NO];
}
/**
Initialization with jobs and Queue handling
**/
-(FileDownloadController *)initWithJobs:(NSInteger)jobs useQueue:(BOOL)queue
{
[self init];
totalJobs = jobs;
maintainQueue = queue;
currentDownloads = 0;
downloadArray = [[NSMutableArray alloc] initWithCapacity:self.totalJobs];
for (int i = 0; i < self.totalJobs; ++i)
{
[downloadArray addObject:[[FileDownloadControllerItem alloc] initwithDelegate:self]];
}
callBackObjects = [[NSMutableDictionary alloc] init];
return self;
}
/**
Download files
**/
-(BOOL)downloadFile:(NSInteger)fileID fileName:(NSString *)name callBack:(id<FileDownloadProtocol>)delegate
{
// Validate file is not already in download queue, cero is not valid id
// Find a free download slot
// If none, clear one
// Configure slot to download file
BOOL error;
FileDownloadControllerItem * downloadItem;
error = [self findJobInQueue:fileID];
if (!error)
{
[self storeSession:fileID callBack:delegate];
downloadItem = [self getFreeSlot:NO];
if (downloadItem == nil)
{
downloadItem = [self getFreeSlot:YES];
}
[self increaseDownloadCounter];
[downloadItem downloadFile:fileID fileName:name callBack:self];
}
return downloadItem != nil;
}
/**
Find if job is already in progress
**/
-(BOOL)findJobInQueue:(NSInteger)job
{
BOOL error = NO;
FileDownloadControllerItem * downloadItem;
for (int i = 0; i < [downloadArray count]; ++i)
{
downloadItem = (FileDownloadControllerItem *)[downloadArray objectAtIndex:i];
if (downloadItem.jobID == job)
{
error = YES;
}
}
return error;
}
/**
Cancel docwnload given its fileID
**/
-(void)cancelDownloadFile:(NSInteger)fileID
{
[self cancelDownload:[self getSlot:fileID]];
}
/**
Call to cancel download activities
**/
-(void)cancelDownload:(FileDownloadControllerItem *)downloadItem
{
if (downloadItem != nil)
{
[self deleteSession:downloadItem.jobID];
[self decreaseDownloadCounter];
[downloadItem.downloadObject stopDownload];
downloadItem.jobID = FREESLOT;
}
}
/**
Stop downloads
**/
-(void)stopAllDownloads
{
for (int i = 0; i < [downloadArray count]; ++i)
{
FileDownloadControllerItem * downloadItem = (FileDownloadControllerItem *)[downloadArray objectAtIndex:i];
[self deleteSession:downloadItem.jobID];
[self decreaseDownloadCounter];
[downloadItem stopDownload];
downloadItem.jobID = FREESLOT;
}
}
/**
Get a worker given a jobid
**/
-(FileDownloadControllerItem *)getSlot:(NSInteger)job
{
FileDownloadControllerItem * downloadItem = nil;
for (int i = 0; i < [downloadArray count]; ++i)
{
downloadItem = (FileDownloadControllerItem *)[downloadArray objectAtIndex:i];
if (downloadItem.jobID == job)
{
return downloadItem;
}
}
return downloadItem;
}
/**
Get a free worker
**/
-(FileDownloadControllerItem *)getFreeSlot:(BOOL)force
{
FileDownloadControllerItem * downloadItem = nil;
FileDownloadControllerItem * downloadItemReturn = nil;
NSDate * minDate = [NSDate dateWithTimeIntervalSinceNow:0];
for (int i = 0; i < [downloadArray count]; ++i)
{
downloadItem = (FileDownloadControllerItem *)[downloadArray objectAtIndex:i];
if ( ( downloadItemReturn == nil && downloadItem.jobID == FREESLOT ) || force)
{
if (force)
{
if ([downloadItem.startTime timeIntervalSince1970] < [minDate timeIntervalSince1970])
{
minDate = [NSDate dateWithTimeIntervalSince1970:[downloadItem.startTime timeIntervalSince1970]];
downloadItemReturn = downloadItem;
}
}
else
{
downloadItemReturn = downloadItem;
}
}
}
if (downloadItem != nil)
{
[self cancelDownload:downloadItemReturn];
}
return downloadItemReturn;
}
- (void) downloadError:(NSError *)error downloadID:(NSInteger)jobID;
- (void) downloadSucceed:(NSMutableData *)data downloadID:(NSInteger)jobID;
downloadController = [FileDownloadController getController];
[downloadController downloadFile:fileID fileName:url callBack:self];
#pragma mark -
#pragma mark FileDownloadProtocol
/**
Notify an error
**/
- (void) downloadError:(NSError *)error downloadID:(NSInteger)jobID
{
// Notify error to screen
}
/**
Notify download complete
**/
- (void)downloadSucceed:(NSMutableData *)data downloadID:(NSInteger)jobID
{
// Do something with the data, remember the jobID is the ID sent in downloadFile
}