Os x

Being that I host a podcast (Or whatever it is called now) we get a large portion of our audience from iTunes and a large portion of them are Mac users. I don’t use Macs, I don’t have any real interest in buying one, but I am curious as to their status from a business perspective. Meaning, am I going to find myself in a situation where I’ll be needing to develop applications on two platforms (Windows and OS X) down the road due to Apple gaining market share, or do you think Apple will continue to not make any further inroads in the PC industry.

And if I end up developing for OS X, what is the programming environment like today? I recently read that at a press conference, they are finally getting garbage control. Which makes me curious as to how strong or weak their development environment is. Anyone with experience want to chime in on the differences between C# and Objective-C, and how Cocoa is to develop for?

I guess I’m just asking because I’m generally interested in the programming environment of the Mac, but don’t feel like going to a Mac forum to get told about everything that is wrong with the Windows platform and not find any substantial answers. And at the same time, I don’t want to read a huge technical journal on the subject either. Just looking for some insight from some folks who have experience in the two platforms and what they consider the situation on the Mac to be like. If that can be found here.

Thanks
K

How to be successful, happy, fulfilled, and drive a totally hot car

The primary language on the Mac is Objective C. It’s an object-oriented variant of C like C++ that according to its proponents is much cleaner. It has some nice Java hooks that it alone can do that makes Java an OK language for it; cf. NeoOffice/J.

The IDE, Xcode, is nice. It’s not WOO WOW GEE WILLIKERS nice, but it’s better than emacs.

Truly, I think the present and future is that most apps for the next 10 years are going to be Web-based. You do it right, and you get platform independence for free.

All in all, what the fuck are you wringing your hands about? It’s just another platform, and you do not have to start wearing black turtlenecks, get a lobotomy or join a cult to use one.

DeepT has said he loathes the Mac platform, but i see he hasn’t chimed in yet.

Sorry if my post was convoluted. I was a bit tired when I wrote it. I’m curious as to how the development environment has matured versus developing on the Windows platform, specifically .NET. I realize I can use Ruby on Rails and push out a web application, but what’s it like working with the Apple API/IDE compared to Windows? How is Apple on backwards compatibility when they do an OS upgrade? What’s the primary desktop SQL package that folks use? Does it have anything like the UAC? Stuff along those lines. Does it feel like Apple is moving in the right direction to make cross platform development easier? Or do you think that Desktop Linux is going to make quicker inroads than OS X?

I’m just trying to get a feel for where the Mac platform is headed, without getting lost in fanboyism. It’s no big deal, I’m just curious.

K

Kevin, I do cross platform development for Windows and OSX. I have an application consisting of about 120 source files that runs on both platforms.

TSG isn’t perfectly accurate in what he says. I loath development on the Mac platform, not Mac’s in general. For the end user, it is the greatest thing since sliced bread.

Ill give you a quick rundown of my experiences so far. Also if you seriously get into Mac Development, stay in contact with me, there is a lot of stuff I have not figured out yet. I am sure there will be a lot we can learn from each other. My area of expertise, if you can call it that, is the “under the hood” stuff to the OS, not GUI stuff. IE: Getting the user name, finding out the network status, looking at the process table and such…

Anyway on to my preview of Mac Development:

Development Environment: XCode 2.4

XCode sits on top of the GNU compiler. It is just a pretty front end for you. There are serious issues that arise because of this. I do not know if it is because of the limitations of the GNU compiler or the ineptitude of the XCode developers. I suspect it is the latter.

Debugging:
XCode’s debugger is very limited compared to Dev Studio.

  1. You can not move the Program counter backwards.

  2. You can not move it forwards.

  3. You can not watch a variable’s value unless XCode sees fit to present you with its value. IE: If you want to see the value of Alpha, and XCode doesn’t happen to automatically show it, you can’t see its value.

  4. Occasionally XCode will lie about a value you see. IE: You see the value of X as 20, then it goes past a statement that says X = 30, and it will still report X as 20.

  5. You can never see ‘static’ values in the debugger. IE: “static unsigned long Timer;” will result in Timer being totally invisible to the debugger.

  6. You can not change a variable’s value via the debugger.

  7. On occasion, even in a full debug mode with no optimizations, the debugger with become out of synch with the actual code shown. Usually it fixes it if you move into or out of a function / method call.

The Source Editor:

  1. It is ok, over all, as far as basic C++ source editors go.

  2. It does not recognize a change when a source file on a disk changes. IE: You tamper with main.cpp and decide to undo the changes, so you grab the latest version from source control. The source editor doesn’t notice and will still show the changed version in your editor. If you compile, it will save it again. The only way I know of to re-synch it is to close the project and open it again. This is a real issue when you have the same source file for windows and OSX and are making changes in two editors at once.

  3. Auto completion for functions is some what wonky, and even when it works, it is not really in a desirable format. In DevStudio you get a tool tip to show you what is next, highlighting the parameter you are on. In XCode it actually dumps out the entire function with stubbed in values.

IE: Say there is a function like “void DoStuff(int N, float X, String Name)”. XCode will put in your source file each time you use DoStuff “DoStuff(<int N>, <float X>, <String Name>)”. Maybe it is just a stylistic thing, but I find it annoying, especially since I can not double click on <float x> and just type the name out. Double clicking would only select “<float” so you need to constantly highlight with the mouse and delete that stuff.

  1. Finding documentation on a highlighted function is iffy. Sometimes it finds it, other times it doesn’t. I mean even on the same exact function. One day it can look up “fstat” and other days it can’t. I have no idea why.

Documentation in general:
This is very poorly organized. There is nearly zero cognitive organization. By that I mean, if you want to find the section on “file management” or “system information”, you won’t find anything. You already have to kind of know where to look and what it is called.

The documentation is also frequently wrong, but not ‘wrong’ in the way MSDN tends to be. On MSDN they will give you source code examples that might not compile because of syntactical problems, or crash because they do something dumb like delete a null pointer. The Apple documentation not only does all this, but will give examples of functions that do not even exist.

I was trying to find out how to be notified when the user was logging out or the system was shutting down. So I am digging and digging on the Apple Site, and find some article on that. It used something like AENotifyRegister or something like that. It gave some sample code. I cut and paste the code, and it doesn’t compile. It doesn’t know what this AENotifyRegister function even is. I have the right headers and all, according to the sample. So I look that function up on apple’s site. It returns 1 result, the example I was just looking at. I google it. It returns 1 result, the page I was looking at. This kind of stuff happens on occasion.

Finally, they have no unified documentation format. If something is a UNIX command, you will get a man page. If its an Apple thing, you will get an Apple page. If you look for a UNIX command via the apple documentation, you get no hits, and vice versa. It really sucks when you have no idea who owns API function such and such.

Overall their documentation is an abomination, but it is all you have to work with.

Compiler / IDE General stuff:

  1. Your files list (source files) doesn’t auto sort. If you make a new file, it will be appended to the list and stay there. Obviously the more source files you have, the more annoying this is.

  2. There are a whole mess of compiler switches you can change, with only the most threadbare documentation. To make matters worse, the ‘default’ configuration is almost never what you want. For example, if you write a function header, but forget to write the body, the compiler will compile it and link it. In DevStudio the linker will not allow this to happen. You run your app, it enters the function and crashes. This can easily happen if you include a header without adding the library associated with it. There is a compiler switch that you can change that will cause the linker to puke in such cases. Why this isn’t the ‘default’ setting, I have no idea.

  3. Changing a project is very convoluted. You can’t just add a CPP file sometimes. You can add it to your build, but then it is not part of your ‘target’ and you need to do some funky stuff to get it to work. God help you if you have multiple targets.

Beyond XCode, general development notes:

I have said a few times in this forum, that OSX is really two OSs. People belittle me when I say this. If you do not accept my word on this, you will have to learn the hard way. The two OSs are, Darwin and Apple.

Darwin is the BSD-like UNIX core. It is pretty much what you expect out of UNIX based operating system. It is stable, secure, and cryptic. Once you understand it such that it is no longer cryptic, you will be happy as the proverbial bug in a rug.

The Apple OS is the big ugly thing that sits on Darwin. It is not secure by any stretch, it is unstable, and absolutely convoluted. It is layered with APIs as old as Mac OS 1.0 all the way up to the new Mac stuff. As one veteran apple developer from their official forums once told me, “Apple doesn’t fix bugs in their API. They just make a new API with new bugs. The newer the API the lest trustworthy it is. Always use the oldest API you can find that will do what you want.”

At this point it really isn’t clear they are two OSs, until you get more ‘under the hood’. The first thing you may notice is that the two OSs do not really talk to each other. If you make an Apple app, and register a signal to be sent when the system shuts down, you will never receive it. Signals are UNIX things, not Apple things.

If you have an Apple app, and try and do some ‘unix’ stuff, it can cause major instabilities in the entire system, not just your app. For example, lets say want to launch an application from your application. You look up the fork command and the exec command. You write your code, which maybe you have done 1000 times before, and compile it. Then you run your application, which might seem to be OK at first. However, sometimes your application will simply disappear from the task list without any reason, not even a crash. Sometimes, although it is very rare, the whole apple shell will crash. It is all because your new application was an Apple app, but launched via the UNIXdisappear system.

Similarly if you make a UNIX app, and then create their standard apple app directory structure, such as package / contents / macos / application and then run it, it is like playing Russian roulette. Most times it may work, but once in a while, something really weird happens.

What I am getting at, is that you need to be very careful when mixing API calls. Most minor calls, like fstat, chmod, and whatnot are quite safe. However, bigger impact ones are more likely to produce odd behavior.

Overall, I would give the Apple Development setup a D-. There is no real excuse for the state it is in. I am quite convinced that Apple spent more money on deciding what color their IPods should be then on the development setup. It is unfortunate they are the only game in town. Borland and Codewarrior no longer support Mac development.

This is excellent, thanks DeepT for the insight. Have you been developing on the platform through major releases? I’m curious if you think they are working to address these issues or are just piling on the crap so-to-speak?

The documentation issue seems like the biggest problem. I could see living with the bugs, but without the knowledge available to research an issue seems like a big concern.

Obviously you work on the cross platform because you think it’s worth it. Do you see this continuing/growing over the next ten years? If you were to start a new project from scratch, would you include OS X development in your design plan? Or just concentrate on the Windows platform moving forward?

Thanks again, very interesting.
K

Our product isn’t a typical one you would try and market.

We make network access control software, which monitors the network and the PCs for various things. For example, if your computer is spamming the network, you get quarantined. If your computer doesn’t have an AV package installed, you get quarantined, etc…

This composes of many parts. The part I am responsible for is the client which is actually installed on your computer. Clearly most users do not want some kind of ‘agent’ on their computer, so they are not really asking for our product.

On the other hand, large institutions do want it installed so maintain network security.

Educational Institutions have requested, for some time, a Mac version of our client. It is not a critical part of the sales of our system, but it sure is a really nice thing to have. Linux is there too, but it is very minor. Nobody has really expressed much concerned in getting a Linux solution. This is partly because there are not that many Linux users around ( compared to windows and Mac), but also because it is assumed that someone who runs a Linux box isn’t a complete idiot and has some concept of network security.

With respect to where Mac’s are going in the next 10 years, I have no idea. Nobody can know. Maybe they will get 20% of the market, maybe they will shrink to 5%. From a developer standpoint, Apple sure isn’t trying very hard to make their job easier. I would sure like to spend an hour or two with Jobbs or the head of their development support projects to point out the things they can do to really help the development community out.

Should you develop cross platform stuff? I suppose that depends on the difficulty of what you are doing, and how many resources you have. If it isn’t much of a cost to do so, then why not?

Lets say that you were making a text editor. Is the GUI really complex? Is most of the work the visual component? Can you get a good Mac programmer? If it is complex, and you can’t get a good Mac programmer, it might not be a good idea. However, I have not done any Mac GUI work. It may be easy to do.

However, if your GUI is simple and all the heavy work is behind the scenes, in code that can be made platform independent, then it might not be that hard to port it to the Mac.

One thing you should be aware of, is that a Mac Application should look and feel like a Mac Application. Don’t make it look like a windows port. It has to be the ‘Mac Experience’.

I can give you some coding guidelines for multi-platform code:

  1. Avoid platform specific API calls as much as possible. For example, in windows there is a DeleteFile() API, which only works on windows. On Unix platforms, the command is unlink(). This command is supported by windows, and you can just use it in place of DeleteFile(). Now your code works on both platforms and doesn’t need a bunch of #ifdef statements all over.

  2. Use as many standard classes as you can. In windows you have a CList container. You maybe be very familiar with it. The rest of the world uses the STL which has its <list> class. Windows has this, use it. CStdString is a great substitute for CString.

  3. Use classes to abstract a platform layer away from your implementation of your code. For example, I have this class called ProcInfo with a bunch of methods about process stuff. So if I have need to know if a process is running, I just use ProcInfo::IsProcRunning(CStdString &Name). On Windows and Mac, the implementation is different, but to my main application, it doesn’t know or care. As a result on the Mac I have a different ProcInfo.cpp then I do on windows. The headers are identical and shared between projects.

  4. Share as much code as you can. Do not have a Mac code base and a Windows code base if you can help it. In my project, which has about 130 files, only 6 differ or are Windows specific or Mac specific. I also only have about 5 #ifdef pairs related to platform abstraction, the rest are debug related. If you change functionality in a shared code segment, then you don’t have to remember to do it in the other code base. Bug fixes in either place fix the bugs for everyone.

  5. Abstract platform / architecture stuff out as well. This is more along the lines of quirks of the platform or how data is managed. For example, I have a NetInfo class which handles network stuff. One method gets the routing table. The routing table has several IP address blocks. On windows, these IP address are backwards, in Little-Endian order. Also on Windows, when getting an IP address of your own box, it comes in Network, or Big-Endian order.

Originally I was doing stuff like FlipLong() here and there trying to keep it straightened out and it became confusing. At some point it is, is it the route entry that is forward or was it the IP address? It was very messy. I made a simple rule to clear it all up. My NetInfo class, always gives and takes IP addresses in Network order. Now all code using this class doesn’t have to know or care. This worked out even better on the Mac, because it has two architectures, Intel and PPC. PPC is Big-Endian, Intel is Little-Endian. None of my main application code has to change because of the rule I made. Only the internals of the Mac or Windows version of the NetInfo class have to figure it out.

Another Platform / Architecture change was to abstract complex data types out. Windows has its own structure for route table entries. Mac’s have a different type. As a result, my NetInfo class has its own external NetInfo_Route type. Everyone uses that, and only on the inside of the NetInfo class does it convert it to the platform specific type.

  1. Try and keep your platform abstracted functions conceptually simple. Going back to my NetInfo class, all its methods are conceptually simple (not implying their implementation is). For example, GetRouteTable, SetRoute, DeleteRoute, etc… Now if I have common need to search the route table for some kind of pattern, lets say local routes or routes on a specific subnet, I do not have a NetInfo method to do this. I have a wrapper class handle this using the basic NetInfo methods. When I have to do the Mac version of the NetInfo class, I still only have those 3 methods to make, and the complex higher level network operations work without me having to write a Mac version of them.

So, what I am saying, is simply to plan your code to be portable from the beginning, and be aware of windows specific stuff in the main code base. If you wait until your main app is ‘done’ and then try to rework it for Macs, it will be a lot more painful. Familiar API’s are not necessarily your friend, and frequently there is a generic alternative that works on both platforms.