Battery replacement in an iPad Pro

Replacing the battery in an iPad Pro is a horrible, terrible repair procedure. It’s all about heat and glue. Jeez.

This sounds like a good idea, but it isn’t. I heated the iOpener in the microwave for 30 seconds on full power as prescribed and it was fairly hot. Let it rest on the iPad for a couple of minutes and the iPad turned maybe lukewarm. Or maybe not even that. It really didn’t work for me.
Continue reading “Battery replacement in an iPad Pro”

A platform too many

With the new iBooks and iTunes U app, I’m missing a piece of the puzzle. Just as truckloads of schools have given the kids MacBooks, Apple rolls out the new textbooks to iPads only. Are we supposed to switch over the schoolkids to iPads now, and lose the OSX apps they use?

It would seem logical that iBooks and iTunes U would be available in versions for OSX as well, but there’s no sign of that. Or is Apple planning on running iOS apps on OSX in something like the iOS simulator? What’s going on here? As it stands now, it makes no sense.

Method forwarding in Objective-C

I scraped together the following from a number of sources and got it to work fine and without compiler warnings. Interesting links are, among others:

http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html
http://macdevelopertips.com/objective-c/objective-c-categories.html

But, I get ahead of myself. The idea here is to have one object forward method invocations to another. Typically, you have a class responding to method A, then you decide to make an instance of that class a member of an outer class and any messages for the methods sent to the outer class should be forwarded to the inner class if that’s where they are to be handled. And, of course, you don’t want to sit and write all these methods again in the outer class just so the inner class gets called. An example:

I have a class I call IotaDOM2TableProxy which has a method “rowsInSection:”. The class IssueWorksheet holds an instance of IotaDOM2TableProxy as a property. I now want any “rowsInSection” messages sent to the outer IssueWorksheet to be forwarded to the inner IotaDOM2TableProxy object without having to declare any “rowsInSection” method for the IssueWorksheet class. This is how you do it.

Firstly: the target, the IotaDOM2TableProxy class, needs no modification at all. It never knows what hit it, or rather, where the invocations come from. So we’ll not say anything more about it than that it contains the declaration of the “rowsInSection:” method (among a load of other stuff):

@interface IotaDOM2TableProxy : NSObject {
...
}
- (NSUInteger)rowsInSection:(NSUInteger)section;
@end

The IssueWorksheet class holds an instance of the IotaDOM2TableProxy, and does not declare any method called “rowsInSection”:

@interface IssueWorksheet : NSObject {
    IotaDOM2TableProxy *dom2tableProxy;
}
@property (nonatomic, retain) IotaDOM2TableProxy *dom2tableProxy;
@end

To make IssueWorksheet forward any calls it doesn’t know about to IotaDOM2TableProxy, we have to override three methods in IssueWorksheet:

- (BOOL)respondsToSelector:(SEL)aSelector {
    return [super respondsToSelector:aSelector] || 
           [self.dom2tableProxy respondsToSelector:aSelector];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *sig;
    sig = [super methodSignatureForSelector:aSelector];
    if (sig == nil)
        sig = [self.dom2tableProxy methodSignatureForSelector:aSelector];
    return sig;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    SEL aSelector = [invocation selector];
    if ([self.dom2tableProxy respondsToSelector:aSelector])
        [invocation invokeWithTarget:self.dom2tableProxy];
    else
        [self doesNotRecognizeSelector:aSelector];
}

And this works beautifully for one, two, or any number of methods to forward. There’s just one problem: the compiler complains that IssueWorksheet “may not respond to method…” and we should always eliminate warnings. The easiest way is to declare the forwarded methods in a category, which only mildly defeats the purpose of the exercise. But it works and is safe. You do that by adding the category after the interface declaration of IssueWorksheet, so the header file will now look as follows in its entirety:

//
//  IssueWorksheet.h
//  iotaPad1
//
//  Created by Martin on 2010-06-08.
//

#import 
#import "IotaDOM2TableProxy.h"

@interface IssueWorksheet : NSObject {
    IotaDOM2TableProxy *dom2tableProxy;
}

@property (nonatomic, retain) IotaDOM2TableProxy *dom2tableProxy;

- (id)initFromFile:(NSString *)name ofType:(NSString *)type;


@end

@interface IssueWorksheet (ForwardedMethods) 
- (NSUInteger)rowsInSection:(NSUInteger)section;
@end

In the above, I call the category “ForwardedMethods”, but you can call it anything you like. The name doesn’t matter and isn’t referenced anywhere else, but the category must have a unique name of some sort.

Please note: there is no implementation in the .m file for “rowsInSection”. The category definition suffices to shut the compiler up.

Use iPad to run Norway

Verbatim quote from the CNN iPhone app today, due to the Icelandic volcanic revenge:

“Jens Stoltenberg, who was in New York for President Barack Obama’s nuclear summit, is running the Norwegian government from the United States via his new iPad, his press secretary Sindre Fossum Beyer said.”

That’s one amazing gadget. Gotta have one.