Sunday, November 07, 2010

Out-Of-Scope, or is it?

It drove me nuts the other day, but seems to be right, you only need to know why.

To make it short, always remember your-self ;)

Subversion 1,2,3

Since Apple moved some of its docs and I hadn't copied my settings of Xcode over to the new computer I just had to spent 20 minutes surfing to find everything again on how to setup Xcode with the local svn.

Actually it's easy:

1. Create a local repository: svnadmin create ./myrepository
2. In Xcode: SCM->Repositories->Add:
- Name: Local
- Scheme: file
- Path: Path to myrepository
3. Import your files to svn through the SCM window, remove them from your harddrive and check them out again
4. (yeah, I said 1,2,3, sorry, but it's already working so this is more for fun) Set the build directory some place else in the project info window, so that the build files don't bloat up you svn

Sunday, March 22, 2009

A new try

So after the last couple of weeks (months....) I started writing some apps. One of them I will rewrite. Now this is kind of odd, since I only started it some weeks back, but the way that it works just doesn't fit the way I want it to work.

First of all, writing CoreData apps when you haven't completely understood CoreData is a pretty bad idea. I have another app running on CoreData, which I will probably keep on it and try to fix all conceptional errors that I added to it, but for this app, I will rewrite it. Will get me some more experience on how apps were created before CoreData existed and hopefully some insights in how things work a bit more.

The app

The app that I am rewriting is all about Apps and Licenses. I want a combination of something like RapidoSerial, LicenseKeeper and a bit more.
The idea is to have the license data and the apps together. This will keep me from manually taking care of app-backups and clean ups and give me some overview on apps that I tested and didn't like. (Currently I test them and three months later test them again, only to find out that I have already tested them).

First things first
I created a new project, created a Mercurial repository and drafted the UI in Interface Builder. I'm not completely happy with it, but it fits my needs for now.

Next thing is to create a class with all the info. I want to have a directory in the ~/Library/ApplicationSupport folder with the Documents that you can save with it and a customizable folder for application versions. The app itself should save it's data in XML, this way you will always have access to the software, even if the app would not work anymore.

So let's get started 

Distributed revision control

As mentioned before I wanted to have versioning setup when getting into coding again. Subversion was a nice way of doing this while I was working on my stationary computer. I had pretty few overhead by Subversion since I only accessed it via "file://" instead of "svn://" of "http://" but this of course only works good as long as you only work on one computer.

My new toy

So the other day I got myself an old iBook (yes, iBook.... I said old :-) ). Mostly to be a bit more flexible. Having a laptop now changes the situation in regards to versioning. If I would always be in my network I could use it, but I want to use it somewhere else, too. So I found myself a couple of different options:
  • creating another Subversion repository on my laptop and manually copying back and forth
  • changing the Subversion access from file to ssh and configuring my router to be available over the internet
  • changing the Subversion access from file to ssh and not having versioning when not logged in my network
  • changing to a centrally available repository (not in my network)
I don't want my router and my pc to be running all time so option two is out. Option 1 means too much manual work and option three simply disqualifies itself by loosing the one thing that mattes to me.... versioning.

A new concept... at least for me
 
I got reminded of an article that I read some time ago. It was about decentralized / distributed versioning systems. Instead of one central repository that you need online to update your working copies, you can copy the repository to your local computer, work on it and later submit the changes back. All of this with keeping full history.
The idea sounded good as it would enable versioning on different computers, even when they are not connected.
Thinking about this more and more I got reminded that Linus Torvalds (creator / godfather of the Linux kernel) uses one of those systems because centralized systems wouldn't fit the needs.

After some surfing I chose Mercurial for a try. It's lightweight and runs on Mac OS X. The only bad thing about it, is that it does not have any Xcode integration. However it works (just as git probably). And I like it.

Sunday, February 01, 2009

nib vs xib

Easy thing.....
  • xib --> xml
  • nib --> binary
That's it. I use version control, so xib is my choice. Xcode creates a nib out of the xib on compile time

Sunday, January 11, 2009

IBOutlet / IBAction Definition

One of the most important concepts of Cocoa (at least to get us started) is the way that Cocoa combines UI and code.
In a Visual Studio project the code that generates the UI is in the same file as the coding itself. 

This is not the case in Cocoa. We have our code completely seperated from the UI, which 
resides in a NIB/XIB file (or several ones).
To get it connected we need to let the code know what interfaces we have and let the UI know what we are working with. We will do this by defining Outlets and Actions in our code, creating an “interface object” in the UI that will be the interface between code and UI and connect the UI elements to that interface.

So what are Outlets and Actions? 
Actions are events which the UI sends to the code when something happens. If you click on a button Cocoa will start the code that you have defined by
  1. linking the button to an action of an “interface object”
  2. calling the method of that action in the code
An Outlet is a link from code to UI. If you want to show or hide an UI element, if you want to get the text of a textfield or enable or disable an element (or a hundred other things) you have to define an outlet of that object in the sources and link that outlet through the “interface object” to the UI element. After that you can use the outlet just like any other variable in your coding.

So let’s get started: 
We’ll create a small app which has a window with a button. As soon as you hit the button, the window will be closed. Not very interesting, but good enough to show how this works.
First of all we will define the outlets. We will only need to call the window to close it, so we only need an outlet  IBOutlet NSWindow *myWindow; The strange thing for me was that we have two definitions for myWindow (IBOutlet and NSWindow)..... but I guess you get used to anything, and that is just the way it goes.
Further we need an action for the time the button gets pressed on the UI. 
-(IBAction)closeWindow:(id)sender;
 
All actions have the IBAction return code (which is the same as void) and the (id)sender as an argument.
Once we saved the file we can switch to the UI in the Interface Builder. Here we add a NSObject whichs Identity we will set to the class in which we added our outlets and actions. Then we create the UI by opening the Window object and dragging a button from the library (Command Shift L) to our window. Now we will set the link from the button to the action. To get this done we need to right click on the button and drag it on the newly created NSObject item. A new popup will appear listing all available actions. You should select the one that you have created. 

After that CTRL-click on the NSObject item. Again a popup will appear listing the outlets that the class has defined. Now we have to drag a line from the outlet (to be precise, from the box right of the outlet) to the window.

Ok, so now we have a class which takes care of the interaction between UI and code; we have our UI, which we attached to the outlets and actions that we defined. So now all what is missing is the code which will do whatever we want when the action gets triggered.
Switch to Xcode and go to the source file to create the method that you want to add. Between the @implementation and the @end enter the method: 

-(IBAction)closeWindow:(id)sender 
     [myWindow orderOut:sender]; 

myWindow is the window of your application (which is a NSWindow instance). The method orderOut hides the window. That’s it!
This way you can also get/set the text of text fields ([textField stringValue]), enable/disable buttons([myButton setEnabled:YES/NO]) or whatever you want.

Saturday, November 22, 2008

Objective-C

In a glance, Objective-C is C plus object orientation and other fun little things.

Now being used to Java and C# for the last couple of years, this of course means one thing that I personally forgot very happily... pointers. But let's take it step by step.

Files and Headers

An Objective-C file has the file ending ".m", the header file has the file ending ".h"

To include the header files into your coding (be it source or other header files) you'll have to write "#import " for global headers (e.g. Cocoa.h) or "#import "headername.h"" for your own local headers. Besides the name (import <-> include) this is pretty much as in C++ (at least how I remember it :-) )

So starting of with, you would include the framework header file in your header file and your header file in your source file.

How Headers are setup

A header file normally includes an import for other headers and a class definition. The class definition consists out of the class name, its deriving object, its variables and its methods.

A simple class definition could look like this:


@interface AppController : NSObject {

int x;

}

@end

Now this class definition would not do to much as it does not have any methods, but it would define a class named "AppController" being derived from NSObject with one integer variable called x.


The definition always starts with "@interface" and ends with "@end"


A method definition in Objective-C will be defined like this:


- (int) setX:(int)y;


This defines a method setX with a return value of type int. To call the method you'll need to pass a variable of type int which can be accessed by the name y. The "-" in front of the method declaration is not a typo, but tells you that this is a "regular" instance method. A global class method would be defined with a "+" instead (comparable with the "static" keyword of Java/C#). The method definition will not be inserted into the curly brackets but between their end and the "@end" so the new class definition would look like this:


@interface AppController : NSObject {

int x;

}


- (int) setX:(int)y;


@end


The source file


To finish off our example here we'll have a quick look at the corresponding source file:


#import "AppController.h"

@implementation AppController


-(int) setX:(int)y

{

//Magic happens here.....

x=y;

return x;

}

@end

This should not be to much of a suprise now. Pretty much straight forward besides the "@implementation" and "@end" commands which simply wrap up the class related coding.