There's really not a decent explanation for this, other than Terminal.app went bonkers. I've seen this happen before to some extent if you have an NSWindow that has transparent background, but a partial background drawing like here is something completely new.
This sort of weird nonsense only happens to me.
If the video link isn't showing up in the RSS feed, here it is for you.
Howdy!
Welcome to my blog where I write about software
development, cycling, and other random nonsense. This is not
the only place I write, you can find more words I typed on the Buoyant Data blog, Scribd tech blog, and GitHub.
Internal Server Error
You may have noticed recently (hopefully not) this site kicking back a simple, plain-text error:
The root of this issue was some scripts inside Drupal simply taking too long and timing out, which I believe, has been resolved by enabling e-accelerator in the site's .htaccess file. I'm hoping that has killed the errors, if it hasn't feel free to drop me a line at tyler@bleepsoft.com and let me know the site is broke again :)
Special thanks to Dave at GeekISP of course for being accommodating with my silly complaints.
An internal server error occurred. Please try again later
The root of this issue was some scripts inside Drupal simply taking too long and timing out, which I believe, has been resolved by enabling e-accelerator in the site's .htaccess file. I'm hoping that has killed the errors, if it hasn't feel free to drop me a line at tyler@bleepsoft.com and let me know the site is broke again :)
Special thanks to Dave at GeekISP of course for being accommodating with my silly complaints.
I ain't Shipley, but PmpMyApp
Ever since coming across the (draft) specification for NAT-PMP I've been almost in love with the absurdly simple NAT port mapping protocol. The unfortunate downside is that NAT-PMP isn't well supported except on Airport base stations, one of which I recently acquired, so as is customary when I welcome a new device into my apartment, I had to write some code for it. I hate to sound like a fan-boy, but like Bonjour, Stuart Cheshire's other baby, NAT-PMP is sickeningly simple. A series of straight-forward UDP packets is all that is needed for a local (inside the NAT) device to create a mapping on the NAT device itself.
To exhibit this functionality, I've created a sample application that uses a tiny little library I built to create and destroy mappings on the NAT-PMP enabled device. The application is called "PmpMyApp" and can be found on GitHub
The code contained in pmpmapper.c has three basic functions that perform the functionalities that NAT-PMP provides, and are aptly named as well:
The pmp_get_public() function returns a pointer to a sockaddr_in that contains the external IP address of the NAT device. The pmp_create_map() function does the heavy-lifting, in that it will create the actual mapping (and the deletion too, with a zero lifetime) and will tell the NAT device to persist the mapping for the number of seconds specified with the lifetime argument. The code is commented so it should be very easy to get a feel for how to use the pmpmapper functions, a good place to start is by examining how it's used in the PmpMyApp source. (Note: All of the PmpMyApp code is BSD licensed)
To exhibit this functionality, I've created a sample application that uses a tiny little library I built to create and destroy mappings on the NAT-PMP enabled device. The application is called "PmpMyApp" and can be found on GitHub
The code contained in pmpmapper.c has three basic functions that perform the functionalities that NAT-PMP provides, and are aptly named as well:
struct sockaddr_in *pmp_get_public();
pmp_map_response_t *pmp_create_map(uint8_t type, uint16_t privateport, uint16_t publicport, uint32_t lifetime);
pmp_map_response_t *pmp_destroy_map(uint8_t type, uint16_t privateport);
The pmp_get_public() function returns a pointer to a sockaddr_in that contains the external IP address of the NAT device. The pmp_create_map() function does the heavy-lifting, in that it will create the actual mapping (and the deletion too, with a zero lifetime) and will tell the NAT device to persist the mapping for the number of seconds specified with the lifetime argument. The code is commented so it should be very easy to get a feel for how to use the pmpmapper functions, a good place to start is by examining how it's used in the PmpMyApp source. (Note: All of the PmpMyApp code is BSD licensed)
Tiring
I am not certain if forgetfulness is a side effect of working too much, or general stress, but I spent about a minute looking around for my keys before finding them still sitting in the lock on my front door.
Whoops.
Whoops.
Mono Winforms Update
The pre-release version of Mono 1.2.3 handles the painting events properly, so it appears that FTGL# actually works on Mono, at least on Windows.
Thanks to the kind folks in #mono-winforms for taking a look at this for me.
Thanks to the kind folks in #mono-winforms for taking a look at this for me.
Kernel Panics Do Weird Things
With the arrival of my new Airport Extreme base station came two new ways I can kernel panic my machine. So I now have 1, 2, 3 ways, three ways to panic my machine, ah-ah-ah-ahhhhh.Besides the usual enjoyment of seeing this wonderful image, you can experience some weird things when your OS X machine reboots.
In the attached video, I found that my mouse was in a perpetual state of scrolling down. Not a quick scroll either, a nice leisurely one, the kind you take on the beach, a nice leisurely scroll down in every window with a scrollbar in the entire operating system. Gak.
In the attached video, I found that my mouse was in a perpetual state of scrolling down. Not a quick scroll either, a nice leisurely one, the kind you take on the beach, a nice leisurely scroll down in every window with a scrollbar in the entire operating system. Gak.
Mono, Winforms, Tao, and Me
I finally got around to testing FTGL# with Mono on Windows. Didn't require any modification, but there's one oddity ...
I don't know yet if it's Mono or Me (I'm usually missing some detail ...) but
C:\Documents and Settings\stephen\My Documents\work\FTGLSharp\sample\bin\Debug>"FTGLSharp Demo.exe"
Opening Font File C:\Windows\Fonts\arial.ttf
Setting 24pt, 72dpi
Done font initialization
sap.ftgl.MainForm, Text: FTGL.OnActivated() called
sap.ftgl.demo.demoControl.forceRefresh()
sap.ftgl.demo.demoControl.OnPaint() called
sap.ftgl.MainForm, Text: FTGL.OnActivated() called
sap.ftgl.demo.demoControl.forceRefresh()
sap.ftgl.demo.demoControl.OnPaint() called
C:\Documents and Settings\stephen\My Documents\work\FTGLSharp\sample\bin\Debug>mono "FTGLSharp Demo.exe"
Opening Font File C:\Windows\Fonts\arial.ttf
Setting 24pt, 72dpi
Done font initialization
sap.ftgl.MainForm, Text: FTGL.OnActivated() called
sap.ftgl.demo.demoControl.forceRefresh()
sap.ftgl.MainForm, Text: FTGL.OnActivated() called
sap.ftgl.demo.demoControl.forceRefresh()
I don't know yet if it's Mono or Me (I'm usually missing some detail ...) but
OnPaint() isn't happening when it should if I fill my control with another control
Absolute Frustration
Time-Warner (again) had an outage this morning, and it has somehow left my Linksys WRT54G absolutely incapable of routing properly.
From the router administration page, I can ping public servers. From inside the network, I can ping ping local machines. I can properly resolve hostnames, I just can't ping anything on the public internet, from inside the network. My router has become absolutely dysfunctional as anything but a simple switch.
I'm only lamenting that I don't know of a taller building from which to hurl this miserable piece of shit from.
From the router administration page, I can ping public servers. From inside the network, I can ping ping local machines. I can properly resolve hostnames, I just can't ping anything on the public internet, from inside the network. My router has become absolutely dysfunctional as anything but a simple switch.
I'm only lamenting that I don't know of a taller building from which to hurl this miserable piece of shit from.
Webservices with Dumbarton
While I have been know to gripe about WebServicesCore, there are however options now when developing service-oriented applications. Introducing, Dumbarton; Dumbarton is basically a ObjC-C# bridge that makes use of the Mono embedded API to allow you to utilize C# code from within your Cocoa application. Personally, I think writing SOAP consumption code in C# using Mono or .NET is far nicer than trying to write something using C/Objective-C via WebServicesCore, so this is my "favorite" option. The word favorite being in quotes as unfortunately Dumbarton is a bit complex to use and bundle for a smaller Cocoa application.
Dumbarton is however an option, so I wrote up a quick example that makes use of a currency exchange rate webservice via xmethods.com and essentially rehashes the proverbial "Currency Converter" sample project with an up to date exchange rate. I've pushed the project to GitHub in case you want to check out the whole project.
Mostly because I'm a lazy developer (who isn't?) I used the standard "wsdl" executable that you can find in .NET or Mono to generate the necessary stub class for providing the last intermediary layer between our desktop application. The method that's generated (synchronous) that we'll write our wrapper for is:
which will handle the actual webservice invocations which we'll write a small Dumbarton wrapper for. Interacting with SOAP webservices in .NET/Mono is quite simple however, so it'd be trivial to take an existing set of generated stubs and modify them, or simply write all the code from scratch.
The Dumbarton wrapper provides the neccessary "boot strapping" for a bridged object between Cocoa and Mono and also "acts" as the bridged object for the C# class. For example, our Dumbarton wrapper class is called CurrencyConverter which is a subclass of DBMonoObjectRepresentation, and in the wrapper method we call:
which will invoke the C# method getRate(string,string) and return a MonoObject pointer. The bridged methods will return a MonoObject pointer which you can either unbox with the DB_UNBOX_* macros provided in the DBBoxing.h file, or you can invoke methods on that object like CurrencyConverter does with:
in order to return a string, or another MonoObject pointer to use. Overall it's really simple to use once you have all the ducks in a row, such as llinking against the Mono.framework and the Dumbarton.framework properly, and you load them into the DBMonoEnvironment appropriately.
I bundled a Dumbarton.framework build that I had handy inside the Subversion repository, but I have linked this against the Mono 1.2.3-preview that I have installed on my machine, so I recommend you checkuot the latest Dumbarton from Subversion (
Depending on your familiarity with developing with C# in either Mono or .NET, Dumbarton may be a great option for utilize existing .NET code for webservices, write cross-platform webservices code, or just avoid the pains of WebServicesCore; it can also be another frustrating stop on the avenue of SOAPy pains if you misunderstand how Dumbarton or C# works. It's currently on my ever lengthening todo list to start documenting far more of what you can do with Dumbarton, but hopefully the examples distributed with the source, along with CurrencyConverter provide a good starting point for those who feel crazy enough to try it out.
As a side note, I have 8.6444 pound in my wallet right now.
Dumbarton is however an option, so I wrote up a quick example that makes use of a currency exchange rate webservice via xmethods.com and essentially rehashes the proverbial "Currency Converter" sample project with an up to date exchange rate. I've pushed the project to GitHub in case you want to check out the whole project.
the nitty gritty
Mostly because I'm a lazy developer (who isn't?) I used the standard "wsdl" executable that you can find in .NET or Mono to generate the necessary stub class for providing the last intermediary layer between our desktop application. The method that's generated (synchronous) that we'll write our wrapper for is:
public System.Single getRate(string country1, string country2);
which will handle the actual webservice invocations which we'll write a small Dumbarton wrapper for. Interacting with SOAP webservices in .NET/Mono is quite simple however, so it'd be trivial to take an existing set of generated stubs and modify them, or simply write all the code from scratch.
The Dumbarton wrapper provides the neccessary "boot strapping" for a bridged object between Cocoa and Mono and also "acts" as the bridged object for the C# class. For example, our Dumbarton wrapper class is called CurrencyConverter which is a subclass of DBMonoObjectRepresentation, and in the wrapper method we call:
[self invokeMethod:"getRate" withNumArgs:2,str1,str2];
which will invoke the C# method getRate(string,string) and return a MonoObject pointer. The bridged methods will return a MonoObject pointer which you can either unbox with the DB_UNBOX_* macros provided in the DBBoxing.h file, or you can invoke methods on that object like CurrencyConverter does with:
(MonoString *)(DBMonoObjectInvoke(rateObj,"ToString",0,NULL))
in order to return a string, or another MonoObject pointer to use. Overall it's really simple to use once you have all the ducks in a row, such as llinking against the Mono.framework and the Dumbarton.framework properly, and you load them into the DBMonoEnvironment appropriately.
notes on CurrencyConverter
I bundled a Dumbarton.framework build that I had handy inside the Subversion repository, but I have linked this against the Mono 1.2.3-preview that I have installed on my machine, so I recommend you checkuot the latest Dumbarton from Subversion (
svn co svn://svn.myrealbox.com/source/trunk/Dumbarton) and install the latest stable version of Mono (1.2.2). If you feel like trying out the preview, you can grab the Mono 1.2.3 preview installer to link your custom Dumbarton build against. Something to note however, is the Installation Path in the Dumbarton Xcode project is set to /Library/Frameworks currently, so if you want to link against it and bundle it inside your application bundle you'll need to update that to @executable_path/../Frameworks and then bundle it in the same fashion you would with Growl or Sparkle. You will also need to setup a copy files or a build script phase to handle your bundling of the DLLs inside the application bundle as well. Distributing an application that uses Mono and Dumbarton is a bit stickier, as you have to pick and choose which libraries to bundle, etc, check out this thread from the mono-osx list.
the springer final thought
Depending on your familiarity with developing with C# in either Mono or .NET, Dumbarton may be a great option for utilize existing .NET code for webservices, write cross-platform webservices code, or just avoid the pains of WebServicesCore; it can also be another frustrating stop on the avenue of SOAPy pains if you misunderstand how Dumbarton or C# works. It's currently on my ever lengthening todo list to start documenting far more of what you can do with Dumbarton, but hopefully the examples distributed with the source, along with CurrencyConverter provide a good starting point for those who feel crazy enough to try it out.
As a side note, I have 8.6444 pound in my wallet right now.
I'm on another podcast
Steve Scott of Late Night Cocoa asked me a couple weeks ago if I wanted to come on and talk about BuildFactory and continuous integration, and then that slowly morphed into talking about webservices and Dumbarton as he noticed I posted some WebServicesCore gripes. We got to chatting a bit about why Mac developers don't seem to "appreciate" webservices as much as those in the .NET world, etc and eventually got together to record Web Services with R. Tyler Ballance.
If you've not checked out Late Night Cocoa, I highly recommend it, it's already shaping up to be a good (technical) podcast about Mac development (the Core Data with Marcus Zarra interview was fantastic, a hard one to follow). If nothing else I hope most developers can use my interview to get a better feel for what's available in the growing webservices (2.0!) landscape. A more active discussion about the strengths and weaknesses in the Cocoa frameworks can do nothing but make the Mac development community stronger, check it out!
If you've not checked out Late Night Cocoa, I highly recommend it, it's already shaping up to be a good (technical) podcast about Mac development (the Core Data with Marcus Zarra interview was fantastic, a hard one to follow). If nothing else I hope most developers can use my interview to get a better feel for what's available in the growing webservices (2.0!) landscape. A more active discussion about the strengths and weaknesses in the Cocoa frameworks can do nothing but make the Mac development community stronger, check it out!
We're all retarded.
I came across this after reading a bit about the "bomb scare" in Boston today, and cannot come to any other conclusion than "we're retarded." In the picture in the article linked above, even I can clearly see that it's really not a bomb, it's hardly even a "device" but nonetheless, these "hoax packages caused alarm in Boston."
I fear that in this age of increased terror-McCarthyism and ridiculous (shallow) security measues, if I were to forget my backback under the table in an outdoor café, I would return later to retrieve it and be greeted by a bomb squad apprehensively approaching my backpack filled with nothing more explosive than a half-eaten roast beef sandwich.
To the staff of "Aqua Teen Hunger Force" it was nice knowing you, and I'm sorry but you're all about to be implicated in an eeeevil terrorist plot to bombard Boston with poor animation; regardless, I hear Cuba has wonderful weather this time of year.
I fear that in this age of increased terror-McCarthyism and ridiculous (shallow) security measues, if I were to forget my backback under the table in an outdoor café, I would return later to retrieve it and be greeted by a bomb squad apprehensively approaching my backpack filled with nothing more explosive than a half-eaten roast beef sandwich.
To the staff of "Aqua Teen Hunger Force" it was nice knowing you, and I'm sorry but you're all about to be implicated in an eeeevil terrorist plot to bombard Boston with poor animation; regardless, I hear Cuba has wonderful weather this time of year.
Basic HTTP Authentication with WebServicesCore
Todd Ditchendorf is the man I have to thank now, not only for his fantastic SOAP Client, but now for "showing me the way" in terms of using CFNetwork to handle basic HTTP authentication with SOAP webservices in Cocoa. Performing the basic HTTP authentication is still an absolute pain in the ass, but it is possible nonetheless.
Without further ado, take it away Todd.
Without further ado, take it away Todd.
Publishing War on the Horizon
Apparently, predictably, and late to the party, research publishers are getting nervous about the push for Open Access. Hopefully this is just an idea for a push from the publishers that will quickly be dropped, but from an article on nature.com (found via slashdot of course):
Public access equals government censorship
I hesitate to even quote that because it's so far off-base. There was more too, but since this is just an article on a potential future publicity campaign I don't really think a thorough response is warranted. If the publishers ever try pushing this BS on the research community I have no doubt the response will not be what the publishers hope.
These publishers have to realize that the entire reason they exist at all is because they have been the best way to make information available to as many people as possible. Publishing researchers want their work to be available and if traditional publishers can't continue to be a relevant way to make that happen then they simply don't have a viable business model. Personally I still think there's value in subscriptions to printed journals, and I'm sure people I work with feel the same.
Public access equals government censorship
I hesitate to even quote that because it's so far off-base. There was more too, but since this is just an article on a potential future publicity campaign I don't really think a thorough response is warranted. If the publishers ever try pushing this BS on the research community I have no doubt the response will not be what the publishers hope.
These publishers have to realize that the entire reason they exist at all is because they have been the best way to make information available to as many people as possible. Publishing researchers want their work to be available and if traditional publishers can't continue to be a relevant way to make that happen then they simply don't have a viable business model. Personally I still think there's value in subscriptions to printed journals, and I'm sure people I work with feel the same.
Twitterbot Is Now Open Source
As I previously mentioned, I've written a small C# application called "Twitterbot" that grabs items from an RSS feed and retrofits them for twitter. After discussing it with some of the folks over at twitter, they have no problem with me open sourcing the litte bot, so I give you, the Twitterbot.
I also added a few fixes this morning after adding the hybridized twitter-thing:
The Twitterbot can be downloaded from the subversion repository, details are located on the Twitterbot's page. The Twitterbot is BSD licensed and will run with both .NET and Mono. Enjoy!
I also added a few fixes this morning after adding the hybridized twitter-thing:
- Improved duplication checks
- Refresh slow-downs between 12:00 and 6:00 am (exclusive)
- Better error handling
- A few comments :)
The Twitterbot can be downloaded from the subversion repository, details are located on the Twitterbot's page. The Twitterbot is BSD licensed and will run with both .NET and Mono. Enjoy!
Twitterbot. No Really, I Need To Be Stopped
Ok, Twitterer almost had a valid excuse, but this is just bloody unnecessary. I wrote a C# (Mono) news bot for twitter last night out of boreom while waiting for a client to finish writing the webservices needed for my project. The Twitterbot is based very loosely on Mario Menti's perl source code, in that I took the tinyurl idea (and that's about it). I wrote the bot with the concept in mind of using one bot to manage all the feeds at once, which does have a slightly undesirable affect of posting the updates for all the feeds at once, but with a bit of tweaking that can be lessened.
The bot is used to run the following twitter-things: googlenews, googlenewsworld, googlenewssports, googlenewsus, googlenewsent
The Twitterbot makes use of RSS.NET for all its incoming feed parsing, but uses the standard System.Net.WebRequest class for posting to both twitter and retrieving the proper tinyurl link. The basic structure of the bot is simple, whenever it grabs new items it'll check that feed's last (stored internally) items to prevent duplication of twitter-posts, and then will shorten the title, generate the tinyurl link and finally post the tiny message to twitter. One of the issues I discovered with Google News is that they randomize the story providers for any given story, i.e. a they might push out a story to their feeds about China's shooting down of a satellite but each time the bot updates that feed may return a different title for the story from a different news organization. In order to prevent flooding, the bot currently has a twitter-posting maximum of two per iteration, which combined with the update interval (30 minutes) helps cut down on both duplicate stories, but also spamming the living hell out of twitter.
The file format that the bot reads feeds and twitter information from is also simple:
I think I am going to release this as open source in the very near future but I want to check with the twitter guys first to take any steps necessary to prevent spamming their goofy little service. I really think my bot would help organizations use twitter as a minimalistic content delivery platform (market-speak!) if they already spit out content in standard RSS formats elsewhere, but I don't want to step on any toes.
A nice and neat little Twitterbot, all in less than 300 lines of code :)
The bot is used to run the following twitter-things: googlenews, googlenewsworld, googlenewssports, googlenewsus, googlenewsent
the technical details
The Twitterbot makes use of RSS.NET for all its incoming feed parsing, but uses the standard System.Net.WebRequest class for posting to both twitter and retrieving the proper tinyurl link. The basic structure of the bot is simple, whenever it grabs new items it'll check that feed's last (stored internally) items to prevent duplication of twitter-posts, and then will shorten the title, generate the tinyurl link and finally post the tiny message to twitter. One of the issues I discovered with Google News is that they randomize the story providers for any given story, i.e. a they might push out a story to their feeds about China's shooting down of a satellite but each time the bot updates that feed may return a different title for the story from a different news organization. In order to prevent flooding, the bot currently has a twitter-posting maximum of two per iteration, which combined with the update interval (30 minutes) helps cut down on both duplicate stories, but also spamming the living hell out of twitter.
The file format that the bot reads feeds and twitter information from is also simple:
<feeds>
<!-- & -> & -->
<feed name="Google News" url="http://news.google.com/news?ned=us&topic=h&output=rss" twitter="user" password="pass"/>
</feeds>
I think I am going to release this as open source in the very near future but I want to check with the twitter guys first to take any steps necessary to prevent spamming their goofy little service. I really think my bot would help organizations use twitter as a minimalistic content delivery platform (market-speak!) if they already spit out content in standard RSS formats elsewhere, but I don't want to step on any toes.
A nice and neat little Twitterbot, all in less than 300 lines of code :)
Thread Cancellation in C#
After some recent frustrations using Thread.Abort() and Thread.Join() in C# I adopted another means of cancelling a thread. In the previous iteration of this code, it was hanging on the following code:
Under certain conditions (such as invoking unmanaged code from C#), the function being executed by the thread "myThread" can cause the Thread.Join(uint) to block indefinitely regardless of what timeout value (in microseconds) is passed as an argument to Join().
Instead of using the Thread class' functions for cancelling a thread, it is much more reliable to use a stay-alive boolean instead in your thread. In my code, the thread serves as a basic runloop that iterates a couple of times a second, so I added the following code:
Elsewhere in the code, instead of calling both Thread.Abort() and Thread.Join(uint), I set threadStayAlive to false, and call Thread.Join(uint) to ensure that the thread is properly cancelled before continuing execution. I've tested this for about an hour or so trying to replicate the infinite-blocking that would occur with Thread.Abort() and Thread.Thread.Join(uint) and I've not been able to lock up my application yet with the stay-alive boolean. Checking the boolean periodically inside the thread function will allow the the code to appropriately clean up after itself instead of relying on Thread.Abort() which may interrupt whatever the thread is executing at any given time leaving your application in an inconsistent state. Catching a ThreadAbortException inside the thread function can help prevent inconsistent thread states, but I've found it's not preventing any amount of thread lock-ups like the stay-alive will.
Regardless of the framework, threading is never something to be undertaken lightly; it is absolutely essential to know what your thread should be doing so you don't end up with race conditions or corrupted objects. Thread handling in C# is relatively straightforward, and certainly not as frustrating as pthreads, but still can have the same general threading related bugs.
myThread.Abort();
if (!myThread.Join(5000)) {
Console.WriteLine("Failed to join secondary thread");
}
Under certain conditions (such as invoking unmanaged code from C#), the function being executed by the thread "myThread" can cause the Thread.Join(uint) to block indefinitely regardless of what timeout value (in microseconds) is passed as an argument to Join().
Instead of using the Thread class' functions for cancelling a thread, it is much more reliable to use a stay-alive boolean instead in your thread. In my code, the thread serves as a basic runloop that iterates a couple of times a second, so I added the following code:
private static readonly object threadLock = new object();
private static volatile bool threadStayAlive = false;
public static void ThreadFunc() {
//...
lock (threadLock) {
if (!threadStayAlive)
return;
}
//...
}
Elsewhere in the code, instead of calling both Thread.Abort() and Thread.Join(uint), I set threadStayAlive to false, and call Thread.Join(uint) to ensure that the thread is properly cancelled before continuing execution. I've tested this for about an hour or so trying to replicate the infinite-blocking that would occur with Thread.Abort() and Thread.Thread.Join(uint) and I've not been able to lock up my application yet with the stay-alive boolean. Checking the boolean periodically inside the thread function will allow the the code to appropriately clean up after itself instead of relying on Thread.Abort() which may interrupt whatever the thread is executing at any given time leaving your application in an inconsistent state. Catching a ThreadAbortException inside the thread function can help prevent inconsistent thread states, but I've found it's not preventing any amount of thread lock-ups like the stay-alive will.
Regardless of the framework, threading is never something to be undertaken lightly; it is absolutely essential to know what your thread should be doing so you don't end up with race conditions or corrupted objects. Thread handling in C# is relatively straightforward, and certainly not as frustrating as pthreads, but still can have the same general threading related bugs.
FTGL#
I neglected to mention it here, but I released some quick code to allow me to write text in OpenGL and C#. It's called FTGL# and hopefully someone besides me will have a use for it.
The wiki page has svn info
Disclaimer: I posted this in the mono category, but haven't actually tested it on mono yet.
Update: I have finally gotten around to actually running this on Mono (version 1.2.2.1) on Windows.
The wiki page has svn info
Disclaimer: I posted this in the mono category, but haven't actually tested it on mono yet.
Update: I have finally gotten around to actually running this on Mono (version 1.2.2.1) on Windows.
WebServicesCore, Why Hath Thou Forsaken Me
I've been hacking around with more webservices-based applications recently (Twitterer for example) and I've also reminded myself what an utter pain in the ass they can be in Cocoa. With twitter, they make available both JSON and XML-based webservices, which is good since they use basic HTTP authentication for their user-specific webservices (i.e. everything but retrieving the public timeline). The XML-based webservices are more or less straight-forward to hack up with Cocoa, all one really needs to do is write a parser (NSXMLDocument) and then make use of the URL loading classes (NSURLConnection, NSMutableURLRequest) to retrieve and process, or POST data. This method of interacting with "webservices" (more wgetting than anything else) is rudimentary at best, and in my personal opinion, isn't as robust as SOAP webservices are. It does however, work. Regardless of the framework, programming language, or geo-orbital location of the moon, they will work because all you're doing is making an HTTP GET and then parsing the results.
The benefit of SOAP webservices however, is the almost "literal" translation of objects encapsulated into SOAP messages, into runtime objects. In effect, if I have a Person object defined in my WSDL and similarly defined in my application (with a good SOAP framework) the objects should be encoded and decoded appropriately when passed via SOAP. The real power of SOAP can be realized when used with ASP.NET (ick) webservices and .NET clients (see ASP.NET - Mono) where you can relatively quickly and easily build and deploy a services-oriented application. That's .NET/Mono however, my work is dealing with NuSOAP and Cocoa, a less than ideal mix.
To start hashing out a Cocoa-webservices-oriented application, your first stop should be at a local pub, brewery, or mayor's office for a good round of intoxication, only after every tissue in your body is soaked with fine casket-aged whiskey will you be prepared to embark on your journey. It's usually best to start with a complete WSDL, you can then use /Developer/Tools/WSMakeStubs to generate what resembles some Objective-C that you can flesh out to some extent to provide an intermediary layer between your sane Cocoa code and the actual SOAP method calls. Cocoa makes SOAP painful. The stub code revolves around one magical "object" WSMethodInvocationRef. Think of WSMethodInvocationRef like you would a sadistic elf that only pops out of his little elf home to kick you in the groin before shouting "TRY AGAIN IDIOT" and scurrying away, there's a bit of magic involved, but mostly pain. Since the invocations will just return a generic "id" type, the only way to really be sure what your webservice invocation returns is to either call [NSObject respondsToSelector:(SEL)] or just trust that the webservice you called will return what you expect, whether it be an NSString, NSDictionary, NSArray, or NSNumber (NSNumber is what's returned in place of numbers and booleans, it's WebServiceCore's cheap way of boxing those primitives). TRY AGAIN IDIOT.
Something else to note is that things you might expect to be able to use, such as basic HTTP authentication are absolutely non-existent in the magic WebServicesCore black-box. With a URL loading-based webservice (JSON, XML) you can just use the delegate method:
And authenticate from there, popping around through the various NSURLConnection delegate methods. I have also experimented with updating the SOAP endpoint to include a URL something like the following:
While one might assume the HTTP subsystem hidden behind that magical WSMethodInvocationRef would handle this appropriately, and translate it to the basic HTTP authentication tokens, it just doesn't work. TRY AGAIN IDIOT.
The alternatives are few and far between if you absolutely need to use SOAP webservices for a certain Cocoa project, I am working on converting a framework that Jonathan Wight wrote to use the URL loading classes in Cocoa, but other than that learn to love WSMethodInvocationRef or plead with your web developers to rewrite their existing webservices with REST, JSON, etc. WebServicesCore is an antiquated pain in the ass, and probably hasn't been updated since Steve Jobs was at NeXT.
TRY AGAIN IDIOT.
The benefit of SOAP webservices however, is the almost "literal" translation of objects encapsulated into SOAP messages, into runtime objects. In effect, if I have a Person object defined in my WSDL and similarly defined in my application (with a good SOAP framework) the objects should be encoded and decoded appropriately when passed via SOAP. The real power of SOAP can be realized when used with ASP.NET (ick) webservices and .NET clients (see ASP.NET - Mono) where you can relatively quickly and easily build and deploy a services-oriented application. That's .NET/Mono however, my work is dealing with NuSOAP and Cocoa, a less than ideal mix.
To start hashing out a Cocoa-webservices-oriented application, your first stop should be at a local pub, brewery, or mayor's office for a good round of intoxication, only after every tissue in your body is soaked with fine casket-aged whiskey will you be prepared to embark on your journey. It's usually best to start with a complete WSDL, you can then use /Developer/Tools/WSMakeStubs to generate what resembles some Objective-C that you can flesh out to some extent to provide an intermediary layer between your sane Cocoa code and the actual SOAP method calls. Cocoa makes SOAP painful. The stub code revolves around one magical "object" WSMethodInvocationRef. Think of WSMethodInvocationRef like you would a sadistic elf that only pops out of his little elf home to kick you in the groin before shouting "TRY AGAIN IDIOT" and scurrying away, there's a bit of magic involved, but mostly pain. Since the invocations will just return a generic "id" type, the only way to really be sure what your webservice invocation returns is to either call [NSObject respondsToSelector:(SEL)] or just trust that the webservice you called will return what you expect, whether it be an NSString, NSDictionary, NSArray, or NSNumber (NSNumber is what's returned in place of numbers and booleans, it's WebServiceCore's cheap way of boxing those primitives). TRY AGAIN IDIOT.
Something else to note is that things you might expect to be able to use, such as basic HTTP authentication are absolutely non-existent in the magic WebServicesCore black-box. With a URL loading-based webservice (JSON, XML) you can just use the delegate method:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
And authenticate from there, popping around through the various NSURLConnection delegate methods. I have also experimented with updating the SOAP endpoint to include a URL something like the following:
http://user:password@bleepsoft.com/some/stupid/url
While one might assume the HTTP subsystem hidden behind that magical WSMethodInvocationRef would handle this appropriately, and translate it to the basic HTTP authentication tokens, it just doesn't work. TRY AGAIN IDIOT.
The alternatives are few and far between if you absolutely need to use SOAP webservices for a certain Cocoa project, I am working on converting a framework that Jonathan Wight wrote to use the URL loading classes in Cocoa, but other than that learn to love WSMethodInvocationRef or plead with your web developers to rewrite their existing webservices with REST, JSON, etc. WebServicesCore is an antiquated pain in the ass, and probably hasn't been updated since Steve Jobs was at NeXT.
TRY AGAIN IDIOT.
WebServicesCore, On The Radar Screen
A little birdie chirped into my email wondering what the radar number for my previous gripings about WebServicesCore, and I figured that for all one of the Apple employees that actually read my inane bullshit, behold:
Radar #4945073 ("WebServicesCore lacks support for basic HTTP authentication")
Let's all cross our fingers and hope for a much needed update to WebServicesCore. If all else fails, we can tap our shoes together and wish for a new web services API right?
(What's that weird rdar url?)
Radar #4945073 ("WebServicesCore lacks support for basic HTTP authentication")
Let's all cross our fingers and hope for a much needed update to WebServicesCore. If all else fails, we can tap our shoes together and wish for a new web services API right?
(What's that weird rdar url?)
No Really, What Are You Doing?
Like an idiot-moth to a bright lamp, I've somehow been sucked into the latest social web 2.0 zomgzomg craze, I think it's just a subconscious geek's desire to be cool, but regardless, you can find my twitter stream at twitter.com/agentdero.
Most of what's attracted me to the site has been their very simple API, which has allowed me to get an application called "Twitterer" up and running in less than a few hours (1, 2, 3). I've not yet released it (no icon!) but i've been using it for the past two days and am quite pleased with it (if I may say so myself). In fact, if you have read this before, you might notice a recent trend in posts about webservices...ahem.
Twitter allows the masses to finally answer the question "what are you doing?"
To which the masses can reply in a most resounding fashion "nothin really."
Most of what's attracted me to the site has been their very simple API, which has allowed me to get an application called "Twitterer" up and running in less than a few hours (1, 2, 3). I've not yet released it (no icon!) but i've been using it for the past two days and am quite pleased with it (if I may say so myself). In fact, if you have read this before, you might notice a recent trend in posts about webservices...ahem.
Twitter allows the masses to finally answer the question "what are you doing?"
To which the masses can reply in a most resounding fashion "nothin really."