Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198

Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198

Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198

Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/extensions/Variables/includes/ExtVariables.php on line 198
ChatKit.framework - iPhone Development Wiki

ChatKit.framework

From iPhone Development Wiki
Revision as of 01:15, 26 June 2014 by Codyd51 (talk | contribs) (Fix typo in title)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
ChatKit.framework
Private Framework
Availabile 3.0 – present
Class Prefix CK
Headers [headers.cynder.me]

ChatKit is a framework designed for handling SMS, iMessage and MMS, and the views for these. iMessage was introduced in iOS 5 under the codename CKMadridService but has since been replaced and fully integrated into ChatKit.

Listener Capabilities

As of iOS 7, things a process can do with this framework is limited by imagent, the backend daemon that processes calls from ChatKit.framework. Imagent uses a property called listener capabilities to determine what each process can do.

Enum Declaration

enum FZListenerCapabilities {
    Status = 1 << 0,
    Notifications = 1 << 1,
    Chats = 1 << 2,
    VC = 1 << 3,
    AVChatInfo = 1 << 4,
    AuxInput = 1 << 5,
    VCInvitations = 1 << 6,
    Lega = 1 << 7,
    Transfers = 1 << 8,
    Accounts = 1 << 9,
    BuddyList = 1 << 10,
    ChatObserver = 1 << 11,
    SendMessages = 1 << 12,
    MessageHistory = 1 << 13,
    IDQueries = 1 << 14,
    ChatCounts = 1 << 15
};

Default Values for Some Common Processes

  • com.apple.springboard
    Status, Notifications, Accounts, Modify Read State, Chat Counts
  • com.apple.MobileSMS
    Status, Notifications, Chats, Transfers, Accounts, ID Queries

Reading a Message

First things first: When I speak about iMessage I include SMS as well.

ChatKit performs some actions when a message is read, but you as a Tweak developer can do even more.

When you read a message in the iMessage App, the notification CKConversationMessageReadNotification is posted.

We can simply listen to this notification using

[[NSNotificationCenter defaultCenter] addObserver:myTarget selector:@selector(readAwesomeMessage:) name:@"CKConversationMessageReadNotification" object:nil];

So whenever the notification is posted, we can control it in the -(void)readAwesomeMessage:(NSNotification *)notification; method.

By looking at the NSNotification documentation we can see that every NSNotification object has an -(NSDictionary *)userInfo method that returns information which was sent with the notification. This method can return NULL if there is no information available.

From my findings I can say that the userInfo dictionary contains a CKIMMessage object for the key CKMessageKey so basically

-(void)readAwesomeMessage:(NSNotification *)notif {

CKIMMessage *msg = notif.userInfo[@"CKMessageKey"]; 
//CKIMMessage *msg = [[notif userInfo] objectForKey:@"CKMessageKey"]; -->long way that does the same as the line above

//...
}

Now you have a CKIMMessage object to use. You should of course verify the object is not NULL before you try to access properties of it. You can have a quick look at CKIMMessage.h and you directly see that it contains a lot of information to use:

@property (nonatomic,retain) IMMessage * IMMessage; //another message object
@property (nonatomic,readonly) NSString * guid; //message id
@property (nonatomic,readonly) NSString * address; //email address to which the message was sent
@property (nonatomic,readonly) NSAttributedString * subject; //subject of the conversation
@property (assign,nonatomic) CKConversation * conversation; //get the conversation in which the message was read. contains a lot of information as well
@property (nonatomic,readonly) NSArray * parts; //a message contains of different parts (CKMessagePart objects)
@property (nonatomic,readonly) NSArray * recipients; //who are in the conversation?
@property (nonatomic,readonly) NSDate * date; //date of reading
@property (nonatomic,readonly) NSDate * timeRead; //time exactly of reading
@property (nonatomic,readonly) CKEntity * sender; //who sent the message? it contains a lot of information as well
@property (nonatomic,readonly) BOOL isiMessage; //which type of message?
@property (nonatomic,readonly) BOOL isSMS; //which type of message?
@property (nonatomic,readonly) BOOL isOutgoing; //are you sending it?
@property (nonatomic,readonly) BOOL isFromMe; //same
@property (nonatomic,readonly) BOOL hasAttachments; //does it contain images or videos?
@property (nonatomic,readonly) BOOL isToEmailAddress; 
...

We will focus on the message parts a little bit more. It allows you to go through the entire message and filter out different types of parts (Text, Images, Videos).

-(void)readAwesomeMessage:(NSNotification *)notif {

CKIMMessage *msg = notif.userInfo[@"CKMessageKey"]; 

if (msg) { //avoid to have an EXC_BAD_ACCESS exception - we avoid trying to access a NULL object

for (CKMessagePart *part in [msg parts]) { //look through all parts of the message - we can safely do that because no one writes messages with thousands of parts.
    
//have a look at http://developer.limneos.net/?framework=ChatKit.framework&header=CKMessagePart.h
//write your code here what you do with each message part.

} 

} 

}

As you can see, it is very easy to implement your own code when the user reads a message. If you want to find out more about the notification's userInfo, you can log it easily:

-(void)readAwesomeMessage:(NSNotification *)notif {

for (NSString *key in [notification.userInfo allKeys]) {
    id value = [notif.userInfo objectForKey:key];
    NSLog(@"Class: %@ - Value : %@",[value class],value);
}

}

This should pretty much print all what is in the userInfo dictionary to the syslog.

Sending a Message in iOS 7

As of iOS 7, you can use something like the following code to send a message programatically. It will automatically decide whether to send as an SMS or iMessage:

//Get the shared conversation list
CKConversationList* conversationList = [CKConversationList sharedConversationList];
//Get the conversation for an address
CKConversation* conversation = [conversationList conversationForExistingChatWithAddresses:[NSArray arrayWithObjects:@"11111111", nil]];
//Make a new composition
NSAttributedString* text = [[NSAttributedString alloc] initWithString:message[@"reply"]];
CKComposition* composition = [[CKComposition alloc] initWithText:text subject:nil];
//A new message from the composition
CKMessage* smsMessage = [conversation newMessageWithComposition:composition addToConversation:YES];
//And finally, send the message in the conversation
[conversation sendMessage:smsMessage newComposition:YES];

Note that this will only work from the MobileSMS process, as [CKConversationList sharedConversationList] is null in other processes.

Useful Links