Showing posts with label MacOSX. Show all posts
Showing posts with label MacOSX. Show all posts

Thursday, June 14, 2012

Using NSFileHandle.writeabilityHandler

I am using [NSFileHandle writeData:] to send data over network in one of my projects, and I found an interesting problem when I run the app with the testing device, which is using iOS 5.1. After 100 bytes of data are sent, the writeData method halts and throws an exception. Results from Google search told me that it is a problem since iOS 5.0, and maybe I should use NSFileHandle.writeabilityHandler, which is introduced since iOS 5.0 / MacOSX 10.7, instead. Unfortunately, I could not find a single example on web about how to use NSFileHandle.writeabilityHandler should be used. After a day of trial-and-error I finally figured out a workable solution, and I will put it here as a reference. However, I must say this solution is only workable, but not elegant, not even close. I believe there must be a better solution than mine out there.

Update:
  • It seems that fileDescriptor can be used directly in send() or sendto()
  • It is better to use send() which will not block this thread
  • Updated the code to end the sending if there is sending error

// Some definitions
BOOL isAtOrAboveIOS5 = [yourfileHandle respondsToSelector:@selector(setWriteabilityHandler:)];
NSMutableData* pendingData = [[NSMutableData alloc] initWithCapacity:1024];

// Try to send data here
// iOS 5 / OSX 10.7 or above
if (isAtOrAboveIOS5 == YES) {
    [pendingData appendData:dataToSend];
    remoteFileHandle.writeabilityHandler = ^(NSFileHandle* thisFileHandle)
    {
        int amountSent = send([thisFileHandle fileDescriptor], [pendingData bytes], [pendingData length], MSG_DONTWAIT);
        if (amountSent < 0) {
            // errno is provided by system
            NSLog(@"Error while sending response: %d", errno);
            amountSent = [pendingData length];
        }
        [pendingData replaceBytesInRange:NSMakeRange(0, amountSent) withBytes:NULL length:0];

        // Finishing
        if ([pendingData length] == 0) {
            thisFileHandle.writeabilityHandler = nil;
        }
    };
} else { 
    [yourfileHandle writeData:dataToSend];
}

My guess of the actual problem when using writeData: after iOS 5.0 is that writeData: just tries to send as much data as possible over the socket in one shot. If there is much data than the socket can accept (this time), exception is thrown. With NSFileHandle.writeabilityHandler set, the code block is executed everytime its fileDescriptor (this time it is a socket) can accept more data. Since there is no method in NSFileHandle which tells you how many data is actually written, I used function sendto() here, but I believe there should be a better implementation exists.

Thursday, October 27, 2011

OSX Lion Boot Options

This is a reminder for myself~

Once Mac OSX Lion starts booting up, you may press the following key combinations for analyzing and/or fixing your system:
  • Command + V => Verbose mode, so you can check what makes your system wait or which error makes it stuck.
  • Command + R => Recovery mode, you can access disk utilities to check and/or fix your disk, access the Internet for solution, and reinstall your OSX.
  • Option => You can select which disk to boot
  • Command + S => Single user mode, the system will boot into terminal mode and login as root. You can also try to check and fix your disk here, via commands (fsck, fsck_hfs etc.)
  • C => Boot CD/DVD rom.

Monday, December 13, 2010

Adding NTFS Write Functionality to OSX

Okay the story is like this: I have Windows, Ubuntu and MacOSX systems in my home and office and sometimes I backup or transfer files using a 8GB USB thumb drive (another way is to use Dropbox). This works perfectly fine until one day I met a 4.x GB file and OOPS! FAT32 filesystem does not allow a single file with that size! As a result, I tried to search for a mulit-platform supported filesystem which also supports large files. I tried NTFS. It works fine with Windows and Ubuntu but it can only be read from MacOSX, without write... When I was going to give up, a friend suggested this Lifehacker article to me (thanks again to my friend!). According to that article, I added NTFS write function to the MacOSX system and now my problem is solved~

The steps are simple:
  1. Download and install MacFUSE from here
  2. Download and install NTFS-3G for Mac OSX from here
  3. Restart your Mac
  4. Enjoy~