【问题标题】:How can I access the image from the MSMessage's layout on the receiving user's end?如何从接收用户端的 MSMessage 布局访问图像?
【发布时间】:2017-03-05 17:07:18
【问题描述】:

我正在制作一个 iMessage 扩展程序,该扩展程序涉及用户来回发送图片。他们都需要能够访问他们从彼此接收到的图像并在自己的一端使用它。例如,如果 USER 1 将一张小狗的图片发送给 USER 2,则消息布局的 image 属性将是小狗的。然后,用户 2 应该能够点击该消息,并且小狗会加载到屏幕上的图像视图中。到目前为止,我不知道该怎么做。

在这里我将布局图像设置为小狗的图像。

@IBAction func sendPicturePressed(_ sender: AnyObject) {

    if chosenImage.image != nil {

        let session = MSSession()
        let message = MSMessage(session: session)
        let conversation = self.activeConversation
        let components = URLComponents()

        let layout = MSMessageTemplateLayout()

        let image = chosenImage.image
        layout.image = image

        message.layout = layout
        message.url = components.url!

        conversation?.insert(message, completionHandler: { (error) in

            self.dismiss()

        })

    }
}

现在,当第二个用户点击小狗时,我想在他们的屏幕上为小狗设置一个图像视图。不完全确定如何,但我想做的是:

override func willBecomeActive(with conversation: MSConversation) {

    imageView.image = conversation.selectedMessage.layout.image

    //There is no image property to access this like I've provided, that's just what I'm trying to accomplish.
}

【问题讨论】:

    标签: ios10 imessage msmessage msmessagetemplatelayout


    【解决方案1】:

    虽然收到消息后您无法访问布局,但您仍然有机会获得它。如果扩展程序启动,消息的布局可以在您的基于MSMessagesAppViewController 的类的-[didReceiveMessage:conversation:] 方法中到达访问。

    在发送方,您可以为您的消息分配一个带有自定义 ID(例如 UUID)的 URL - 它始终可以访问 - 然后在接收方将其与图像一起提取到 didReceiveMessage 并在本地缓存后者ID 作为名称。这是代码草稿:

    - (NSURL*) fileURLFromRawURL:(NSURL*)idURL
    {
        NSString *fileID = idURL.relativePath;
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileID];
    
        return [NSURL fileURLWithPath:path];
    }
    
    - (MSMessage*) composeMessageWithImage:(UIImage*)image session:(MSSession*)session
    {    
        MSMessageTemplateLayout *layout = [MSMessageTemplateLayout new];
        layout.image = image;
    
        MSMessage *message = [[MSMessage alloc] initWithSession:session];
        message.layout = layout;
        message.URL = [NSURL fileURLWithPath:[[NSUUID UUID] UUIDString]];
    
        return message;
    }
    
    - (void) didReceiveMessage:(MSMessage *)message conversation:(MSConversation *)conversation 
    {
        // Assuming that the extension is launched:
        MSMessageTemplateLayout *layout = message.layout;
        UIImage *img = layout.image;  // you've got the image
        NSURL *path = [self fileURLFromRawURL:message.URL];
        if (path && image){
            NSData *data = UIImageJPEGRepresentation((UIImage*)resource, 0.8);
            [data writeToURL:path options:NSDataWritingAtomic error:nil];
        }
    }
    

    之后,一旦点击消息,-[didSelectMessage:conversation:] 将被调用。在这里你可以再次获取 URL 并从缓存中读取对应的图像(如果可用):

    - (void) didSelectMessage:(MSMessage *)message conversation:(MSConversation *)conversation
    { 
        NSURL *path = [self fileURLFromRawURL:message.URL];
        if (path){
            NSData *imageData = [NSData dataWithContentsOfURL:path];
            UIImage *img = [UIImage imageWithData:imageData];
        }
    }
    

    不要忘记为nils 添加所有必要的检查,成功创建 URL 等。

    【讨论】:

    • 这太棒了!其实这个文件在layout.mediaFileURL中已经可以访问了,所以只需要复制即可。这在任何地方都有记录吗? message.layout 是一个没有可访问成员的 MSMessageLayout 对象,因此必须将其强制转换为 MSMessageTemplateLayout 有点令人担忧。
    • 啊,但刚刚意识到,正如您所说,它仅适用于在扩展程序处于活动状态时到达的消息。真可惜。不知道为什么 Apple 不提供这些数据。
    • 因为您的扩展程序创建的数据需要有一个上下文;否则,您可以访问脚本中任何消息中的任何图像,无论它是否来自您的扩展程序。
    【解决方案2】:

    您无法访问其他用户发送的布局图像。 https://forums.developer.apple.com/thread/53174

    预期选择的消息具有 nil 布局。已收到 消息不会填充布局对象。

    你可以,在发送方,你不仅插入一个带有图像布局的MSMessageMSConversation,还上传一个图像副本到你的服务器,并在MSMessage.URL中标记网络图像URL。

    所以下次用户选择消息时,您可以解开MSMessage.URL 并找到图片网址,然后从您的服务器下载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      相关资源
      最近更新 更多