First - I know private frameworks/APIs won't get me to the AppStore, this is for private use/research only.
I can't get my project to compile with ChatKit.framework
.
Basically I need to somehow init a CKDBMessage
object and get stuff from it.
The first approach I tried is to be able to call this:
CKDBMessage* msg = [[CKDBMessage alloc] initWithRecordID:lastID];
NSLog(@"GOT SMS: %@", msg.text);
I couldn't get it to compile with any combination of these solutions:
CKDBMessage.h
to my projectChatKit.framework
ChatKit.framework
file itselfI have the headers and the framework file in Headers
folder and I tried adding any/all of these build settings, both on recursive/non-recursive:
$(PROJECT_DIR)/Headers
$(SRCROOT)/Headers/ChatKit.framework/Headers
$(SRCROOT)/Headers
$(SRCROOT)/Headers
$(SRCROOT)/Headers/ChatKit.framework/Headers
Always Search User Paths is always on YES
The second thing I tried was to do everything at runtime, this is what I have:
Class CKDBMessage = NSClassFromString(@"CKDBMessage");// objc_getClass("CKDBMessage");
SEL sel = @selector(initWithRecordID:);
NSMethodSignature *signature = [CKDBMessage methodSignatureForSelector:sel];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.selector = sel;
[invocation setArgument:&lastID atIndex:2];
[invocation invoke];
NSObject * msgWeak = [CKDBMessage alloc];
[invocation getReturnValue:&msgWeak];
NSObject *msg = msgWeak;
NSString *text = [msg performSelector:@selector(text)];
NSLog(@"text: %@", text);
Here I crash at invocationWithMethodSignature:
because NSClassFromString returns nil instead of the class...
Any ideas on any of the two approaches?
This is for nonjailbroken, iOS8(.2), using Xcode6
Well not many people viewed this, but for the sake of our wiki community, I managed to solve this by adding the CKDBMessage.h
file to my project (actually I added all the headers of ChatKit
but I don't think it's necessary), than I loaded the framework dynamically with dlopen
like so:
dlopen("/System/Library/PrivateFrameworks/ChatKit.framework/ChatKit", RTLD_LAZY)
So my full solution is:
dlopen("/System/Library/PrivateFrameworks/ChatKit.framework/ChatKit", RTLD_LAZY);
Class CKDBMessageClass = NSClassFromString(@"CKDBMessage");
CKDBMessage *msg = [[CKDBMessageClass alloc] initWithRecordID:lastID];
NSString *text = msg.text;
NSLog(@"text: %@", text);
Getting the ID of the last message involves another framework: IMDPersistence
:
//SomeFile.h
// ...
//declare the function:
static int (*IMDMessageRecordGetMessagesSequenceNumber)();
// SomeFile.m
// ...
//open IMDPersistence framework
void *libHandleIMD = dlopen("/System/Library/PrivateFrameworks/IMDPersistence.framework/IMDPersistence", RTLD_LAZY);
//make/get symbol from framework + name
IMDMessageRecordGetMessagesSequenceNumber = (int (*)())dlsym(libHandleIMD, "IMDMessageRecordGetMessagesSequenceNumber");
// get id of last SMS from symbol
int lastID = IMDMessageRecordGetMessagesSequenceNumber();
Now you can use lastID
to get the message contents...