问题
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:
- Simply add only
CKDBMessage.h
to my project - Add all the headers of
ChatKit.framework
- Add also
ChatKit.framework
file itself
I 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:
- Framework Search Paths ->
$(PROJECT_DIR)/Headers
- Header Search Paths ->
$(SRCROOT)/Headers/ChatKit.framework/Headers
$(SRCROOT)/Headers
- User Header Search Paths ->
$(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
回答1:
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...
回答2:
Currently, I am using XCode 10. here we can see one MessagesKit.framework
in PrivateFrameworks
path. MessagesKit.framework
contains SOMessageHelper
file where we can see sendSMS
function.
Function :
(void)sendMessageText:(id)arg1 toRecipient:(id)arg2 withCompletionBlock:(CDUnknownBlockType)arg3;
来源:https://stackoverflow.com/questions/29151710/import-chatkit-i-e-private-framework-or-using-ckdbmessage-somehow