Thursday, February 14, 2019

HomeEasyBudget : Easy Budget For Your Personnal Finances

Your household budget everywhere, all the time

 Sign Up for Free !

Manage your personal finances

HomeEasyBudget allows you to manage your finances independently of your banking applications.
It is an application made for you who like to manage your finances manually, to the nearest penny and forecast.

Unlike a bank account aggregator (such as Linxeo, Bankin or your bank application) HomeEasyBudget does not access your account data online: no security risk, bank account piracy and no problem with your bank account confidentiality.

You want precise and daily management? HomeEasyBudget allows you to enter all your transactions at any time and from all your devices, and to schedule recurring transactions.

You want a management forecast? HomeEasyBudget allows you to create lines of provisioning and to plan your budgets holidays, works, important purchases, savings, … 

HomeEasyBudget remembers for you which operations you have entered or modified and when

You close a bank account? HomeEasyBudget allows you to keep the history of your old accounts indefinitely.

Schedule your operations

HomeEasyBudget allows you to schedule your recurring transactions for easy management of your daily finances.

You can plan your monthly, weekly, bi-monthly, quarterly and annual transactions with or without a planning deadline.

You can also create custom repetitions

Analyze your finances


With HomeEasyBudget create graphical reports or tables to analyze your accounts and quickly visualize your expenses and revenue items by category, sub-category, monthly, annually or any other period or criterion at your convenience.


HomeEasyBudget offers simple reports already configured for each bank account for quick viewing of your transactions, for a month or a year.

For a more detailed analysis you can also create your own reports on multiple criteria: period, fiscal years, bank accounts, categories, subcategories, amounts, means of payment, third parties, …

Share with your family

HomeEasyBudget allows you to share your account with your all the member of your family or with the people who share a bank account with you like your roommates, associates, …

Share and keep control

Share one or more of your accounts with any other HomeEasyBudget user.
Each share can be controlled by means of rights for each account: consultation only, possible modification, possible reconciliation or permission to create or not a planned operation.

Association or other accounts

HomeEasyBudget’s account sharing allows you to easily create an account for an association and share it with all members of the association’s office, including those who only have to view the account and not modify it with permissions sharing.

HomeEasyBudget also facilitates the creation of a cash account for an event such as an evening, a sports event or a birthday. Create the account and share it with all the managers of the event.

HomeEasyBudget allows you to check your accounts easily and quickly through reconciliations.

Transactions reconciliations

The reconciliation feature allows you to check your transactions at the end of the month or when you receive your bank statement.
The reconciliations allows you to check if your finances are perfect: no forgotten operations, error of entering a credit or debit, duplicate transactions, etc.
With the help of an account statement and the search function, the reconciliation is even faster. For example, you can search for point-based transactions based on an amount, a third party, a category, or a date.

Go back

HomeEasyBudget keeps the history of all your reconciliations and also allows you to cancel them in case of error or doubt.
 

HomeEasyBudget is available for all your devices: Windows PC, Mac OS, Android or iOS mobile phone, Android tablet, iOS or Windows. As an application or from any internet browser.
HomeEasyBudget is an application in the cloud that allows you to do your accounts anytime, anywhere: at home, at work, on public transport, on holidays, …
 

 Sign Up for Free !

 

Wednesday, October 19, 2011

Asynchronous web service client using NSURLConnection and SBJSON

The NSURLConnection class
A NSURLConnection object is used to perform the execution of a web service using HTTP.
When using NSURLConnection, requests are made in asynchronous form. This mean that you don't wait the end of the request to continue, but you do something else until the NSURLConnection object tell you that some data arrived or the connection started, failed on ended.
When initializing the NSURLConnection object you have to pass the reference of a delegate. This is the object called by NSURLConnection to inform your program about the status on the connection.
This delegate must have to implement the following methods  :
  • connection:didReceiveResponse : called after the connection is made successfully and before receiving any data. Can be called more than one time in case of redirection.
  • connection:didReceiveData : called for each bloc of data.
  • connectionDidFinishLoading : called only one time upon the completion of the request, if no error.
  • connection:didFailWithError : called on error.

The Google Books service
In this example, we will use the Google Book web service. We selected this service mainly for the easy of use and the concise results. We also selected this service because it use JSON to return the datas, and JSON is the best data interchange format for mobile devices like iPhone because it's lightweight and easy to parse.
A typical request to the search function of the Google Book web service is :
https://www.googleapis.com/books/v1/volumes?q=biologie
where searchterms are replaced by the searched keywords. You can see by clicking on the preceding link that the service return an array of items consisting of books description.
We will extract the volumeInfo/title, volumeInfo/description, volumeInfo/imageLinks/smallThumbnail and volumeInfo/previewLink in this example.

Integrating SBJSon
Unfortunately, neither the MacOS X nor the iOS SDK have some JSON parsing API, despite the fact that Apple use JSON intensively in their own applications.
There is several third party API that can easily be found on the Internet, and we selected SBJSon for this example.
You need to download the latest SBJSon distribution, extract it somewhere and import it in your XCode project under a new group :



Writing the Book business class
The Book class represent a book with only the attributes we need in the example: a title, a description, a thumbnail image and a URL to the book page. A Book object will be initialized using a JSON string corresponding to a single item from the Google Book web service.
This is the interface :
#import <Foundation/Foundation.h>

@interface Book : NSObject {
    NSString *title;
    NSString *desc;
    UIImage *smallThumbnail;
    NSURL *url;
}

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *desc;
@property (nonatomic, retain) UIImage *smallThumbnail;
@property (nonatomic, retain) NSURL *url;

-(id) initWithJSONDictionnary:(NSDictionary*)json;

@end


and the implementation :
#import "Book.h"

@implementation Book

@synthesize title, desc, smallThumbnail, url;

-(id) initWithJSONDictionnary:(NSDictionary*)json {
    self = [super init];
    if (self) {
        NSDictionary* volumeInfo = [json objectForKey:@"volumeInfo"];
        self.title = [volumeInfo objectForKey:@"title"];
        self.desc = [volumeInfo objectForKey:@"description"];
     
        NSString* path = [[volumeInfo objectForKey:@"imageLinks"] objectForKey:@"smallThumbnail"];
        UIImage* image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:path]]];
        self.smallThumbnail = image;
        [image release];
     
        self.url = [NSURL URLWithString:[volumeInfo objectForKey:@"previewLink"]];
    }
    return self;
}

-(void) dealloc {
    [url release];
    [desc release];
    [title release];
    [smallThumbnail release];
    [super dealloc];
}

@end







The GoogleBookService class
This class implements the code to query the Google Books web service using HTTPS and translate the JSON resulting datas into Books business objects.
The resulting objects are stored in a NSMutableArray collection of Books, and the search is started by the -performSearch function :
#import <Foundation/Foundation.h>


@interface GoogleBooksService : NSObject {
    NSMutableArray *books;
    NSMutableData *data;
}

@property (nonatomic, retain) NSMutableArray *books;

-(void) performSearch:(NSString*)keyword;

@end


The data instance variable will be used by the same callbacks to store the raw datas received from by the NSURLConnection object.

Implementing the GoogleBookService class
The first thing is of course to write the -dealloc destructor :
-(void) dealloc {
    [data release];
    [books release];
    [super dealloc];
}


The -performSearch allocate the temporary data storage, build the URL using the keyword (note that you can build a better URL by encoding/escaping the keyword, not done here for clarity), build a NSURLRequest object using the URL then execute the request using NSURLConnection :
-(void) performSearch:(NSString*)keyword {
    data = [[NSMutableData alloc] init];


    NSURL *url = [NSURL URLWithString:

                     [NSString stringWithFormat:
                         @"https://www.googleapis.com/books/v1/volumes?q=%@"
                             keyword]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
                                                                  delegate:self];
    if (!connection) {
        // this is better if you @throw an exception here
        NSLog(@"error while starting the connection");
        [data release];
    }
 
}


The request to the web service will be executed in a background thread by the connection object. This thread will call the callback functions, in order :
connection:didReceiveResponse, after the connection object have received the response and HTTP headers from the remote web server :
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [data setLength:0];
}

connection:didReceiveData, for each block of raw data received :
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)someData {
    [data appendData:someData];
}

connection:didFailWithError, in case of error :
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [connection release];
    [data release];
}

connectionDidFinishLoading, at the end of the request, if no error have happened. In this function we use SBJSon to translate the raw datas in Books objects :
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];
    NSString *jsonString = [[NSString alloc] initWithData:data
                                                 encoding:NSUTF8StringEncoding];
    [data release];

    NSArray* jsonItems = [[jsonString JSONValue] objectForKey:@"items"];
    id item;
    books = [[NSMutableArray alloc] init];
    for (item in jsonItems) {
        Book* book = [[Book alloc] initWithJSONDictionnary:item];
        [books addObject:book];
    }
    [jsonString release];
}

Friday, October 14, 2011

How to schedule the execution of a function using NSTimer

The NSTimer class
The NSTimer class can be used to schedule the execution of a function in a program for MacOS X, iPhone /  iOs.
You can execute a function for any object, pass some user defined datas, and optionally you can repeat the scheduled execution automagically.

The target function
First, you have to write the target function.
This function must have a NSTimer* parameter because you can use it with multiple timers.
In this exemple, the target function called timerEnd stops the animation of a UIActivityIndicatorView called indicator then posts a notification if the user have entered some text in a UITextField named textNom :

-(void) timerEnd: (NSTimer *) theTimer { 
    [indicator stopAnimating]; 
    if ([textNom.text length] > 0) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"My Notification"  
                                                            object:textNom.text]; 
    } 
    textNom.text = @""; 
} 

Scheduling the timer
Once you have your target function ready, you can schedule the execution using the +NSTimer:scheduledTimerWithTimeInterval class function.
In the following example, the timer execute the [self timerEnd] message after 5 seconds :

[NSTimer scheduledTimerWithTimeInterval: 5.0  
                                 target: self  
                               selector: @selector(timerEnd:)  
                               userInfo: nil  
                                repeats: NO];





Notes on NSTimer
Never forget that NSTimer relies on the run loop. It means :

  • You must have a run loop. If you write a MacOS X console application, you must write it yourself. If you write a library or a Framework, you must document the fact that a run loop is mandatory.
  • Run loops retain timers. So you can release your timers once scheduled.
  • It's not real time. The run loop execute the timers once it have checked that the timer time have been passed. Hence in the preceding example the "after 5 seconds" and not "in 5 seconds".
  • the +NSTimer:scheduleTimer* functions creates the timer and pushes it in the run loop. If you only want to create the timer use +NSTimer:timerWithTimeInterval functions then use -NSRunLoop:addTimer to push the timer (you can use +NSRunLoop:currentRunLoop to get the current run loop).