我NSData
用于发送和接收文本、图片和语音等消息。为了区分消息的类型,我附加了一个标题。当消息到达时,我为NSString
对象分配标头并用于[header isEqualToString:@"txt"]
确定不同的操作。
这是我处理到达消息的方法:
int msgarrvd (void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
void *payloadptr = message->payload;
int payLoadLen = message->payloadlen;
NSLog(@"%d", payLoadLen);
NSMutableArray *msgArray = [NSMutableArray array];
NSData *dataHeader = [NSData dataWithBytes:payloadptr length:3];
NSStringEncoding strEncode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF8);
NSString *header = [[NSString alloc] initWithData:dataHeader encoding:strEncode];
NSLog(@"header:%@", header);
if ([header isEqualToString:@"txt"]) {
// text message
NSData *content = [NSData dataWithBytes:payloadptr length:payLoadLen];
NSString *msgContent = [[NSString alloc] initWithData:content encoding:strEncode];
NSString *subStr = [msgContent substringFromIndex:3];
[msgArray addObject:subStr];
}
if ([header isEqualToString:@"pic"]) {
// pic message
}
if ([header isEqualToString:@"voc"]) {
// voice message
NSMutableData *voiceData = [NSMutableData data];
[voiceData appendData:[NSData dataWithBytes:payloadptr length:payLoadLen]];
[voiceData replaceBytesInRange:NSMakeRange(3, payLoadLen) withBytes:payloadptr];
NSFileManager *fm = [NSFileManager defaultManager];
NSString *voicePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingString:@"sound.wav"];
[fm createFileAtPath:voicePath contents:voiceData attributes:nil];
NSURL *voiceURL = [NSURL fileURLWithPath:voicePath];
[msgArray addObject:voiceURL];
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionary];
if ([header isEqualToString:@"txt"]) {
[myDictionary setObject:header forKey:@"header"];
}
if ([header isEqualToString:@"pic"]) {
[myDictionary setObject:header forKey:
@"header"];
}
if ([header isEqualToString:@"voc"]) {
[myDictionary setObject:header forKey:@"header"];
}
[myDictionary setObject:msgArray forKey:@"content"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageCome" object:nil userInfo:myDictionary];
MQTTClient_freeMessage(&message);
MQTTClient_free(payloadptr);
return 1;
}
Xcode 抛出-[__NSArrayM length]: unrecognized selector sent to instance 0x17dc7bb0
并Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x17dc7bb0'
到底是什么问题?
任何帮助都应该不胜感激!
更多的
- (void)handle:(NSNotification *)notification
{
NSDictionary *message = [NSDictionary dictionaryWithDictionary:[notification userInfo]];
NSString *msgType = [message objectForKey:@"header"];
if ([msgType isEqualToString:@"txt"]) {
NSArray *array = [message objectForKey:@"content"];
NSString *msg = [[array valueForKey:@"description"] componentsJoinedByString:@""];
[self.messages addObject:msg];
NSLog(@"%@&%lu", msg, (unsigned long)[self.messages count]);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
if ([msgType isEqualToString:@"pic"]) {
// process pic
}
if ([msgType isEqualToString:@"voc"]) {
[self.messages addObject:[message objectForKey:@"content"]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
}
这是我的观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle:) name:@"MessageCome" object:nil];
context void * NULL 0x00000000
topicName char * "/test" 0x16dcbe24
*topicName char '/' '/'
topicLen int 0 0
message MQTTClient_message * 0x16dcc064 0x16dcc064
struct_id char [4] ""
struct_version int 4 4
payloadlen int 28675 28675
payload void * 0x4409004 0x04409004
qos int 1 1
retained int 0 0
dup int 0 0
msgid int 25864 25864
payloadptr void * 0x4409004 0x04409004
payLoadLen int 28675 28675
msgArray __NSArrayM * @"1 object" 0x16dcc280
[0] NSURL * @"file:///var/mobile/Applications/417171BD-60C5-4DF6-989D-2983426B9CAD/Library/Documentationsound.wav" 0x16dd0760
dataHeader _NSInlineData * 3 bytes 0x16d48420
strEncode NSStringEncoding 4 4
header __NSCFString * @"voc" 0x16dca530
myDictionary __NSDictionaryM * 2 key/value pairs 0x16dd0830
[0] (null) @"content" : @"1 object"
[1] (null) @"header" : @"voc"
content NSData * nil
msgContent NSString * nil
subStr NSString * nil
voiceData NSMutableData * nil
fm NSFileManager * nil
voicePath NSString * nil
voiceURL NSURL * nil
这是我的 tableView 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.messages count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.textLabel.text = [self.messages objectAtIndex:indexPath.row];
}
// Configure the cell...
cell.textLabel.text = [self.messages objectAtIndex:indexPath.row];
return cell;
}