【发布时间】:2016-12-31 21:52:45
【问题描述】:
在 iOS10 的 iMessage Extensions 中,当用户点击交互式消息气泡时:
如何在发送的消息中保存自定义信息,以便在被点击时,扩展程序能够获取该自定义信息并识别被点击消息的类型以做出相应的响应?
谢谢!
【问题讨论】:
在 iOS10 的 iMessage Extensions 中,当用户点击交互式消息气泡时:
如何在发送的消息中保存自定义信息,以便在被点击时,扩展程序能够获取该自定义信息并识别被点击消息的类型以做出相应的响应?
谢谢!
【问题讨论】:
MSMessage 的url 属性是您可以存储自定义数据的地方。
您也可以使用iMessageDataKit 库。它使设置和获取数据变得非常容易,例如:
let message: MSMessage = MSMessage()
message.md.set(value: 7, forKey: "user_id")
message.md.set(value: "john", forKey: "username")
message.md.set(values: ["joy", "smile"], forKey: "tags")
print(message.md.integer(forKey: "user_id")!)
print(message.md.string(forKey: "username")!)
print(message.md.values(forKey: "tags")!)
它还支持存储数组。
(免责声明:我是iMessageDataKit的作者)
【讨论】:
我只是通过查看Apple's Ice Cream Sample Code 才知道的。
创建要发送的 MSMessage 时,使用 NSURLComponents 对象将自定义信息保存在其 QueryItems 属性中。
示例:
MSMessage* message;
NSURLComponents* urlComponents;
// init
message = [[MSMessage alloc] init];
urlComponents = [NSURLComponents componentsWithURL:[NSURL URLWithString:@"http://yourwebsite.com"] resolvingAgainstBaseURL:NO];
// Saving Custom Information as query items.
[urlComponents setQueryItems:@[[NSURLQueryItem queryItemWithName:@"messageType" value:@"1"],
[NSURLQueryItem queryItemWithName:@"username" value:@"Jorge"],
[NSURLQueryItem queryItemWithName:@"userId" value:@"99999"],
[NSURLQueryItem queryItemWithName:@"userPhoto" value:@"http://yourwebsite.com/9999.jpg"]]];
// Setting message's URL
[message setURL:[urlComponents URL]];
最终到达网址:
添加到 MSMessage 的最终 URL 最终将是:
URL 中的这些额外查询项将被忽略。我的意思是,如果您的网站不打算处理这些查询项,那么当用户点击该消息气泡并从 iOS 版本低于 10(iOS9、iOS8、 ...)。
我在这里看到的唯一缺点是自定义信息暴露给用户(打开 URL 时)。也许 Apple 应该在 MSMessage 中创建一个 userInfo 属性。
接收消息
这就是您从收到的消息中提取信息的方式:
MSMessage* message;
NSString* messageType, *username, *userId, *userPhoto;
// init
message = [self.activeConversation selectedMessage];
if (message)
{
NSURLComponents *urlComponents;
NSArray* queryItems;
// Extracting message URL's coponents. With this URL we'll able to figure out the type of the message.
urlComponents = [NSURLComponents componentsWithURL:[message URL]
resolvingAgainstBaseURL:NO];
queryItems = [urlComponents queryItems];
// Extracting info from the query items.
for (NSURLQueryItem* item in queryItems)
{
if ([[item name] isEqualToString:@"messageType"])
messageType = [item value];
else if ([[item name] isEqualToString:@"username"])
username = [item value];
else if ([[item name] isEqualToString:@"userId"])
userId = [item value];
else if ([[item name] isEqualToString:@"userPhoto"])
userPhoto = [item value];
}
}
【讨论】:
由于这是一个 iOS 10 问题,我希望 Swift 中的以下答案对其他人有所帮助。 (@jmoukel 的原始答案,我刚刚转换为 Swift)。
let message = MSMessage()
guard let url = NSURL(string: "http://yourwebsite.com") else { return }
guard let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false) else { return }
urlComponents.setQueryItems([
"messageType": "1",
"username":"Jorge",
"userId":"99999",
"userPhoto":"http://yourwebsite.com/9999.jpg"
])
message.setURL(urlComponents.URL!)
【讨论】: