Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BalloonImage is missing when cell message contain Media #43

Closed
WarisSaqi opened this issue Nov 16, 2015 · 32 comments
Closed

BalloonImage is missing when cell message contain Media #43

WarisSaqi opened this issue Nov 16, 2015 · 32 comments

Comments

@WarisSaqi
Copy link

I am using SOMessagging in my app and its behaving very inconsistent when images and text is showing in same thread. Some times ballonImage is not shown in text as seen in pics. Its clearly seen that text and balloonImage both are not shown but they both exist there and options are appear. Tell me how could i handle it, thanks in advance.

simulator screen shot 16-nov-2015 12 24 51 pm
simulator screen shot 16-nov-2015 12 25 12 pm
simulator screen shot 16-nov-2015 12 25 31 pm
simulator screen shot 16-nov-2015 12 25 36 pm

@WarisSaqi
Copy link
Author

No, ballon image is there i check it while debugging.

@bintu1234
Copy link

@WarisSaqi Hi did you find any solution I am also facing same issue please help me

@WarisSaqi
Copy link
Author

@bintu1234 i found the solution here is the detail

there is a method setMessage in SOMessageCell.m i mistakenly commit the line [self setInitialSizes] after un-commiting it my issue is solved, check may be this can help you out too.

  • (void)setMessage:(SOMessage *)message
    {
    _message = message;

    [self setInitialSizes];
    [self adjustCell];
    }

@bintu1234
Copy link

Thanks for the Replay but in my case setMessage is fine when i am sending images it is showing nothing like below
image
when i am go back and come it will be like "NULL" in place image
image

so can you please help me

@WarisSaqi
Copy link
Author

can you please paste some code where you are sending images. and then displaying the images in cell. so that i can help you out.

@bintu1234
Copy link

[self.chatHistoryArray removeAllObjects];
//open database
[DBObject copyFileToDocumentPath:@"Chat" withExtension:@"db"];
[DBObject open];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *myJID=[defaults valueForKey:@"userNameJID"];
//assign value in array
messageArray=[DBObject AllRowFromTableName:@"chatTable" withUserID:myJID withFriendID:chatWithUser];
for (int i=0; i<[messageArray count]; i++)
{
message=[[Message alloc] init];
if (imgURL==0)
{
message.type=SOMessageTypeText;
// message.text=[[messageArray objectAtIndex:i] msg];
if ([[messageArray objectAtIndex:i] lft_rght]==0) {
message.fromMe=YES;
}
else{
message.fromMe=NO;
}
}
else if (imgURL!=0)
{
message.type=SOMessageTypePhoto;
// message.media=[messageArray objectAtIndex:i];
if ([[messageArray objectAtIndex:i] lft_rght]==0) {
message.fromMe=YES;
}
else{
message.fromMe=NO;
}
}
if (message.type==SOMessageTypePhoto) {
message.media=[_data base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
}
else
{
message.text=[[messageArray objectAtIndex:i] msg];

                }
NSString *dateString =[[messageArray objectAtIndex:i] tim_dte];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"HH:mm,yyyy/MM/dd"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
message.date=dateFromString;
[self.chatHistoryArray addObject:message];
[DBObject closeDatabase];
    //reload chat

[self refreshMessages];

This is my fetching method from sqlite and sending images here

NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
[body setStringValue:strText];

NSXMLElement *messageBody = [NSXMLElement elementWithName:@"message"];
[messageBody addAttributeWithName:@"type" stringValue:@"chat"];
[messageBody addAttributeWithName:@"to" stringValue:chatWithUser];
[messageBody addChild:body];

if (SendImage) {
NSData *dataF = UIImageJPEGRepresentation(SendImage, 0.5);
imgStr=[dataF base64EncodedStringWithOptions:0];
NSXMLElement *ImgAttachement = [NSXMLElement elementWithName:@"attachement"];
[ImgAttachement setStringValue:imgStr];
[messageBody addChild:ImgAttachement];
[[[self appDelegate] xmppStream] sendElement:messageBody];
}

@bintu1234
Copy link

sorry for my coding standards i am new to ios

@WarisSaqi
Copy link
Author

No issue for coding
actually you are fetching the chats from Chat.db but not saving the new sendimage in Chat.db that is why its null after coming back to view. When you are sending image to other user save it in the database too to show it anytime you come to the conversation

if (SendImage) {
NSData *dataF = UIImageJPEGRepresentation(SendImage, 0.5);
imgStr=[dataF base64EncodedStringWithOptions:0];
NSXMLElement *ImgAttachement = [NSXMLElement elementWithName:@"attachement"];
[ImgAttachement setStringValue:imgStr];
[messageBody addChild:ImgAttachement];
[[[self appDelegate] xmppStream] sendElement:messageBody];

        SaveYour dataF in Database here

    }

@bintu1234
Copy link

@WarisSaqi Hi thanks for the replay actually what i am doing is when i send the image i will send it to server and from there i am getting image url so i am inserting that imageurl in sqlite as a string and have any sample code for chatting for somessaging i googled but no result please help me out

@WarisSaqi
Copy link
Author

@bintu1234 i check your code why are you using third party base 64 encoding as now apple sdk available for base64 encoding and decoding. And the other thing you are saving the url then why are you using the base64 encoding decoding direct use sdWebImage to show the image from url.

@bintu1234
Copy link

@WarisSaqi Thanks for the replay I will try SDWebImage thanks for your suggestion and one more thing is when i am sending image all the above conversations are changed to images and showing blank even bubble image is there any problem with my conditions.

@WarisSaqi
Copy link
Author

@bintu1234 one more thing i noted in your account that you are closing your database right after the adding the object in your array while loop is still running and its calls every time till loop end why are you doing so and for sending image you are sending the base64 string to other user as image while you are saying that you sen the image to server and then send the url of image in chat. Its wrong use the same thing on both end base64 string or url which ever you prefer and save both in your db right after you send or receive the image and one more thing that add this receiving or sending image should be in your messages array before you refresh the SOMessaging tableview.

@bintu1234
Copy link

@WarisSaqi Thanks for the advise and why base 64 means my client want some animation while sending and recieving images so i just feel that it is possible by base64 string so i just use the base64 and thanks for your valueble time based on your answers i think i am missing something inserting and retriving in sqlite any way thanks if any thing i miss can i ask you

@WarisSaqi
Copy link
Author

@bintu1234 yes sure anytime.

@bintu1234
Copy link

@WarisSaqi I tried my level best for sending the images but i am unable to handle please help me out how you will send the messages in somessaging will you please share some code to sending text as well as image i am struggling from last 2 weeks please help me thanks in advance

@WarisSaqi
Copy link
Author

@bintu1234 Here is top overview of the Sending and receiving images using XMPP framework in SOMessaging.

Sending:

Get image from UIImagePickerController.
Get NSData from image.
Send NSData to my server.
Take url from server against the data i sent.
Send this URL to other user.
Save image data in my app DB.

Receiving:

Receive image URL from user.
Download image from Server.
Save image in app DB.
Show the image in SOMessaging.

Here is the code example

- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
    [picker dismissViewControllerAnimated:NO completion:^{
    }];

    UIImage* selectedImage = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage];
    if (!selectedImage) {
        selectedImage = (UIImage*)[info objectForKey:UIImagePickerControllerEditedImage];
    }

    [SVProgressHUD showWithStatus:@"" maskType:SVProgressHUDMaskTypeBlack];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    [self performSelector:@selector(sendImage:) withObject:selectedImage afterDelay:1.0];
}

- (void)sendImage:(UIImage *)image{
    NSString *myJID =  // your Jabber id
    XMPPJID *jid  =  // receipt Jabber id

    //API Call to upload Picture on Tellmo Server
    UIImage *compressedImage = [UIImage compressImage:image compressRatio:0.9f];
    NSData *imageData = UIImageJPEGRepresentation(compressedImage, 1.0);
    if (imageData != nil) {
        NSDictionary *paramDict = //your API call perimeter to upload image on your own server

        [SharedAPIManager callWebserviceForMethod:kAPI_UploadFile WithParam:paramDict withCompletionHandler:^(APIManager *response) {
            if (response.data) {
                // Settings Up Message To Send
                NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
                // Send XMPP Message
                NSXMLElement *messageToSend     = [NSXMLElement elementWithName:@"message"];
                [messageToSend addAttributeWithName:@"type" stringValue:@"chat"];
                [messageToSend addAttributeWithName:@"date" stringValue:[NSDate getStringFromDate:[NSDate date] withFormat:@"yyyy-dd-mm HH:MM:ss"]];
                [messageToSend addAttributeWithName:@"to"   stringValue:[jid full]];

                [body setStringValue:response.data];
                [messageToSend addChild:body];

                [xmppStream sendElement:messageToSend];
            }
        }];

        // Show in UI
        Message *soMessage          = [[Message alloc] init];
        soMessage.fromMe            = YES;
        soMessage.date              = [NSDate date];
        soMessage.type              = [self messageTypeFromString:MessageTypeImage];
        soMessage.thumbnail         = image;
        soMessage.media             = UIImageJPEGRepresentation(compressedImage, 1.0);
        soMessage.text              = @"Image";

        [self saveMessageInDB:soMessage];
    }
}

Receiving Side:

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
    NSString *messageText       = [[message elementForName:@"body"] stringValue];
    NSString *messageSender     = [[message attributeForName:@"from"] stringValue];

    Message *soMessage          = [[Message alloc] init];
    soMessage.fromMe            = NO;
    soMessage.date              = [NSDate date];

    //            id photoElement             = [message elementForName:@"photo"];

    if ([messageText rangeOfString:@"your server file location string"].location != NSNotFound) {
        NSString *urlString = messageText;

        soMessage.type          = SOMessageTypePhoto;
        soMessage.text          = @"Image";
        NSURLRequest *request   = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];

        [[SDWebImageDownloader_Tellmo sharedDownloader] downloadImageWithURL:request.URL options:SDWebImageDownloaderContinueInBackground progress:^(NSUInteger receivedSize, long long expectedSize) {
        } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
            if (finished) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    soMessage.thumbnail     = [UIImage imageWithData:data];
                    soMessage.media         = data;
                    [self saveIncomingMessage:message soMessage:soMessage messageSender:messageSender];
                });
            }
        }];
    }
    else{
        soMessage.type              = SOMessageTypeText;
        soMessage.text              = messageText;
        if (messageText) {
            [self saveIncomingMessage:message soMessage:soMessage messageSender:messageSender];
        }
    }
}

I am using XMPP framework to do all chatting stuff and KissXML for xml creating all stuff relating to XML.
And for image compression i am using UIImage+ImageCompress category.
Handle other scenarios according to your requirements.

@bintu1234
Copy link

@WarisSaqi Thank you so much for the replay let me try

@bintu1234
Copy link

@WarisSaqi Hi i don't want disturb you but i am unable to handle with the above code can you please help me how to handle images and text in somessaging please help me your are the last hope

@WarisSaqi
Copy link
Author

@bintu1234 , I am unable to understand that what is the thing you are unable to handle?
Whether its text or image. SoMessaging itself provide the functionality for handling Text and Images separately by using SOMessageType which include SOMessageTypeText, SOMessageTypePhoto, SOMessageTypeVideo and SOMessageTypeOther. And you just have to set the SOMessage type to Text or Photo.

@bintu1234
Copy link

@WarisSaqi yes but when i send image remaining all are showing as images even text also so thats why i am asking at sqlite end only we need to save the url of image right ?

this is my fetching method from DB
-(void)fetchDataFromDatabase
{
//clear prevous chat history array
[self.chatHistoryArray removeAllObjects];
//open database
[DBObject copyFileToDocumentPath:@"Chat" withExtension:@"db"];
[DBObject open];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *myJID=[defaults valueForKey:@"userNameJID"];
//assign value in array
messageArray=[DBObject AllRowFromTableName:@"chatTable" withUserID:myJID withFriendID:chatWithUser];
for (int i=0; i<[messageArray count]; i++)
{
messageForText=[[Message alloc] init];
messageForText.type=SOMessageTypeText;
if ([[messageArray objectAtIndex:i] lft_rght]==0) {
messageForText.fromMe=YES;
}
else{
messageForText.fromMe=NO;
}

    messageForText.text=[[messageArray objectAtIndex:i] msg];
    NSString *dateString =[[messageArray objectAtIndex:i] tim_dte];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"HH:mm,yyyy/MM/dd"];
    NSDate *dateFromString = [[NSDate alloc] init];
    dateFromString = [dateFormatter dateFromString:dateString];
    messageForText.date=dateFromString;
    [self.chatHistoryArray addObject:messageForText];

    [DBObject closeDatabase];
    //reload chat
    [self refreshMessages];
}
       }

@WarisSaqi
Copy link
Author

@bintu1234 Yes you only need to save the url of image in Sqlite or NSData of Image.

@bintu1234
Copy link

@WarisSaqi okay but while sending image we need to give the type as somessagphoto but it is not taking when i am fetching from DB it is showing as URL in chat can you please help me if you don't mine can you check my code if you want i will send my code

@WarisSaqi
Copy link
Author

@bintu1234 , i check your code your issue is in this following lines of code

for (int i=0; i<[messageArray count]; i++)
{
messageForText=[[Message alloc] init];
messageForText.type=SOMessageTypeText;
if ([[messageArray objectAtIndex:i] lft_rght]==0) {
messageForText.fromMe=YES;
}
else{
messageForText.fromMe=NO;
}

here you can see that you set type of every message to SOMessageTypeText. I Bold that particular line.

@WarisSaqi
Copy link
Author

@bintu1234 , I look your code i found something that may cause the issue
for (int i=0; i<[messageArray count]; i++)
{
messageForText=[[Message alloc] init];
messageForText.type=SOMessageTypeText;
if ([[messageArray objectAtIndex:i] lft_rght]==0) {
messageForText.fromMe=YES;
}

the line i bold is the issue you have to check whether the message is text or photo if text then set type to SOMessageTypeText otherwise set the type to SOMessageTypePhoto

@bintu1234
Copy link

@WarisSaqi i tried like you said but same result if possible check my entire project then it will be help full like life saver please

@WarisSaqi
Copy link
Author

@bintu1234 , ok mail me i will check it tomorrow.

@bintu1234
Copy link

@WarisSaqi thank you so much please send me your mailId

@WarisSaqi
Copy link
Author

@WarisSaqi
Copy link
Author

@bintu1234 , Go into your ASNMessageChat.m and replace your fetchFromDatabase method with this one

-(void)fetchDataFromDatabase {
 //clear prevous chat history array

[self.chatHistoryArray removeAllObjects];
 //open database
[DBObject copyFileToDocumentPath:@"Chat" withExtension:@"db"];
[DBObject open];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *myJID=[defaults valueForKey:@"userNameJID"];
//assign value in array
messageArray=[DBObject AllRowFromTableName:@"chatTable" withUserID:myJID withFriendID:chatWithUser];
 NSLog(@"%@",imageView.image);`
    for (int i=0; i<[messageArray count]; i++) {

        Message *msg=[[Message alloc] init];

        //Change by Waris
        NSString *urlString = [[messageArray objectAtIndex:i] msg];

        NSURL *url = [NSURL URLWithString:urlString];
        if (url)
        {
            //Check whether the url is proper url for your uploaded image or not
            if ([urlString rangeOfString:@"your specific url for image string to compare that whether its a url for image or some website url. Kindly put your some part of image url here" options:NSCaseInsensitiveSearch].location != NSNotFound) {
                msg.type=SOMessageTypePhoto;
                NSData *dataImage = [NSData dataWithContentsOfURL:url];
                msg.media= dataImage;
                msg.thumbnail = [UIImage imageWithData:dataImage];

                //Put Image as text by yourself so that in main screen subdetail you can show it.
                msg.text = @"Image";

            }
            //If url is not image url that means its a website url put it through in text SOMessage will handle it.
            else {
                msg.type=SOMessageTypeText;
                msg.text = urlString;
            }
        }
        else
        {
            msg.text = urlString;
        }


        if ([[messageArray objectAtIndex:i] lft_rght]==0) {
            msg.fromMe=YES;
        }
        else{
            msg.fromMe=NO;
        }        

        //No need to format the date SOMessaging will handle it.
        msg.date = [NSDate date];

        [self.chatHistoryArray addObject:msg];        
    }

    [DBObject closeDatabase];

    //reload chat
    [self refreshMessages];
}

@bintu1234
Copy link

@WarisSaqi Thank you so much Sir really you saved me it's working now thank you

@WarisSaqi
Copy link
Author

@bintu1234 , you are welcome...

@bintu1234
Copy link

@WarisSaqi if you don't mind can you please have a look on this issue #47 please. I tried but unable to get the solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@WarisSaqi @bintu1234 and others