Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Native Objective-C calls from cpp/qt (IOS Email-call)
Forum Updated to NodeBB v4.3 + New Features

Native Objective-C calls from cpp/qt (IOS Email-call)

Scheduled Pinned Locked Moved Solved Mobile and Embedded
6 Posts 2 Posters 2.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Online
    J Online
    J.Hilk
    Moderators
    wrote on 2 Mar 2018, 14:30 last edited by
    #1

    Hello everyone,

    I'm trying send E-Mails with attachments that are created by my application. Because this is only really possible with native IOS/Objective-C code, I created the following simple (pure x-code) example that upon a button press shows the Mail-App:

    - (IBAction)showEmail :(id)sender{
        //Email Subject
        NSString *emailTitle = @"Test Email";
        
        //Email Content
        NSString *messageBody = @"ios programming is so fun!";
        
        //To Address
        NSArray *toRecipents = [NSArray arrayWithObject:@"support@myCompany.com"];
        
        MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
        mc.mailComposeDelegate = self;
        
        [mc setSubject:emailTitle];
        [mc setMessageBody:messageBody isHTML:false];
        [mc setToRecipients:toRecipents];
        
        [self presentViewController:mc animated:YES completion:NULL];
    }
    
    - (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error{
        switch (result) {
            case MFMailComposeResultCancelled:
                NSLog(@"Mail cancelled");
                break;
            case MFMailComposeResultSaved:
                NSLog(@"Mail saved");break;
            case MFMailComposeResultSent:
                NSLog(@"Mail sent");break;
            case MFMailComposeResultFailed:
                NSLog(@"Mail sent failure: %@", [error localizedDescription]);
                break;
            default:
                break;
        }
        
        [self dismissViewControllerAnimated:YES completion:NULL];
    }
    

    this works fine, EMail window appears and sends the E-Mail away without problem.

    To intereate this now in cpp/Qt, U create a native c-interface:

    //ObjectiveCInterface.h
    #ifndef __OBJECTIVECINTERFACE_H__
    #define __OBJECTIVECINTERFACE_H__
    
    class MyClassImpl
    {
    public:
        MyClassImpl (void);
        ~MyClassImpl (void);
    
        void init (void);
    
        void showEmail(char * aCstr);
    
    private:
        void * self;
    };
    
    #endif
    
    

    and a cpp/objective c - combi class

    //MyObject.h
    #import "ObjectCInterface.h"
    #import <Foundation/Foundation.h>
    
    @interface MyObject : NSObject
    {
    
    }
    
    - (void)showEmail:(char *) aCStr;
    
    @end
    
    //MyObject.mm
    #import "MyObject.h"
    #import <UIKit/UIKit.h>
    #import <MessageUI/MessageUI.h>
    
    @implementation MyObject
    
    MyClassImpl::MyClassImpl( void ) : self(NULL){
        init();
    }
    
    MyClassImpl::~MyClassImpl( void ){
        [(id)self dealloc];
    }
    
    void MyClassImpl::init( void ){
        self = [ [MyObject alloc] init];
    }
    
    
    void MyClassImpl::showEmail(char *aCstr){
        NSLog(@"logMyMessage");
        [(id)self showEmailPopup:aCstr];
    }
    
    
    - (void) showEmailPopup:(char *)aCStr{
        NSLog(@"LogMyMessage in Obj");
        NSLog([NSString stringWithUTF8String:aCStr]);
    
    /* Code From working X-Code Project
        //Email Subject
        NSString *emailTitle = @"Test Email";
        
        //Email Content
        NSString *messageBody = @"ios programming is so fun!";
        
        //To Address
        NSArray *toRecipents = [NSArray arrayWithObject:@"support@myCompany.com"];
        
        MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
        mc.mailComposeDelegate = self;
        
        [mc setSubject:emailTitle];
        [mc setMessageBody:messageBody isHTML:false];
        [mc setToRecipients:toRecipents];
        
        [self presentViewController:mc animated:YES completion:NULL];
    */
    }
    
    @end
    
    
    //Mainwindow
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include "ObjectCInterface.h"
    
    #include <QPushButton>
    #include <QVBoxLayout>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow), _impl( NULL )
    {
        ui->setupUi(this);
    
        QPushButton *btn = new QPushButton("Email");
        connect(btn, &QPushButton::clicked, this, &MainWindow::btnClicked);
        QVBoxLayout *lay = new QVBoxLayout(ui->centralWidget);
        lay->addWidget(btn);
    
        init();
    }
    
    void MainWindow::btnClicked(){
        qDebug() << "BtbClicked";
        showNativeEmail();
    }
    
    MainWindow::~MainWindow()
    {
        if(_impl)
        {
            delete _impl;
            _impl = NULL;
        }
        delete ui;
    }
    
    void MainWindow::init()
    {
        _impl = new MyClassImpl();
    }
    
    void MainWindow::showNativeEmail()
    {    
        _impl->showEmail((char*)("Path/to/Attachment.pdf"));
    }
    
    

    So far so good, when I press the Button in my QMainWindow I do get the NSLog entry "Path/To/Attachment.pdf"

    But when I now copy and paste the working code from the X-Code Project into my MyObject.mm class I do get a couple of warnings and when I run the program I get a sigbart-crash.
    in the Line

    [self presentViewController:mc animated:YES completion:NULL];
    

    Clearly I'm missing something. Anyone got an Idea what it could be ?


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    0
    • J Online
      J Online
      J.Hilk
      Moderators
      wrote on 5 Mar 2018, 07:18 last edited by J.Hilk 3 May 2018, 07:22
      #5

      Never mind, @SGaist , I managed to make it work.

      //ObjectCInterface.h
      #ifndef __OBJECTIVECINTERFACE_H__
      #define __OBJECTIVECINTERFACE_H__
      
      class MyClassImpl
      {
      public:
          MyClassImpl (void);
          ~MyClassImpl (void);
      
          void init (void);
      
          void showEmail(char * aCstr);
      
      private:
          void * self;
      };
      
      #endif
      
      //MyObject.h
      #import "ObjectCInterface.h"
      #import <Foundation/Foundation.h>
      #import <UIKit/UIKit.h>
      #import <MessageUI/MessageUI.h>
      
      @interface MyObject : UIViewController  <MFMailComposeViewControllerDelegate>
      {
      
      }
      
      - (void)showEmailPopup:(char *) aCStr;
      
      @end
      
      //MyObject.mm
      #import "MyObject.h"
      
      @implementation MyObject
      
      
      MyClassImpl::MyClassImpl( void ) : self(NULL){
          init();
      }
      
      MyClassImpl::~MyClassImpl( void ){
          [(id)self dealloc];
      }
      
      void MyClassImpl::init( void ){
          self = [ [MyObject alloc] init];
      }
      
      
      void MyClassImpl::showEmail(char *aCstr){
          NSLog(@"logMyMessage");
          [(id)self showEmailPopup:aCstr];
      }
      
      
      - (void) showEmailPopup:(char *)aCStr{
          NSLog(@"LogMyMessage in Obj");
          NSLog([NSString stringWithUTF8String:aCStr]);
      
          //Email Subject
          NSString *emailTitle = @"Test Email";
          
          //Email Content
          NSString *messageBody = @"ios programming is so fun!";
          
          //To Address
          NSArray *toRecipents = [NSArray arrayWithObject:@"support@MyCompany.com"];
          
          MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
          mc.mailComposeDelegate = self;
          
          [mc setSubject:emailTitle];
          [mc setMessageBody:messageBody isHTML:false];
          [mc setToRecipients:toRecipents];
          
          UIViewController * topController = [UIApplication sharedApplication].keyWindow.rootViewController;
          while (topController.presentedViewController){
              topController = topController.presentedViewController;
          }
          
          [topController presentViewController:mc animated:YES completion:NULL];
      }
      
      
      - (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error{
          switch (result) {
              case MFMailComposeResultCancelled:
                  NSLog(@"Mail cancelled");
                  break;
              case MFMailComposeResultSaved:
                  NSLog(@"Mail saved");break;
              case MFMailComposeResultSent:
                  NSLog(@"Mail sent");break;
              case MFMailComposeResultFailed:
                  NSLog(@"Mail sent failure: %@", [error localizedDescription]);
                  break;
              default:
                  break;
          }
          
          [controller dismissViewControllerAnimated:YES completion:NULL];
      }
      
      @end
      
      

      Now I'll have to find out how to add the MessageuiFramework to my *.pro file to compile it usccessfully in QtCreator . But thats an other topic I guess.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 4 Mar 2018, 20:07 last edited by
        #2

        Hi,

        On which line exactly do you have that failure ?
        Which version of Qt are you using ?
        Which version of Xcode ?
        Which iOS version are you targeting ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        J 1 Reply Last reply 5 Mar 2018, 05:52
        0
        • S SGaist
          4 Mar 2018, 20:07

          Hi,

          On which line exactly do you have that failure ?
          Which version of Qt are you using ?
          Which version of Xcode ?
          Which iOS version are you targeting ?

          J Online
          J Online
          J.Hilk
          Moderators
          wrote on 5 Mar 2018, 05:52 last edited by
          #3

          Hi @SGaist ,
          thanks for your time, I'm really a novice with objetcive-c so I'm struggeling quite a bit.

          On which line exactly do you have that failure ?

          that would be in this line:

          - (void) showEmailPopup:(char *)aCStr{
              NSLog(@"LogMyMessage in Obj");
              NSLog([NSString stringWithUTF8String:aCStr]);
          
              //Email Subject
              NSString *emailTitle = @"Test Email";
              
              //Email Content
              NSString *messageBody = @"ios programming is so fun!";
              
              //To Address
              NSArray *toRecipents = [NSArray arrayWithObject:@"support@myCompany.com"];
              
              MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
              mc.mailComposeDelegate = self;
              
              [mc setSubject:emailTitle];
              [mc setMessageBody:messageBody isHTML:false];
              [mc setToRecipients:toRecipents];
              
          //!---------------------This Line------------------
              [self presentViewController:mc animated:YES completion:NULL];
          }
          

          the xcode error is:

          ***Terminating app due to uncaught exception 'NSInvalidArgumentException', reason '-[MyObject presentViewController:animated:completion:] unrecognized selector sent to instance 0x1c001e8f0'
          

          My guess would be I didn't initialize 'self' correctly ?

          Which version of Qt are you using ?

          I'm using Qt 5.10.1

          Which version of Xcode ?

          Version 9.2(9C40b)

          Which iOS version are you targeting ?

          Deployment Target is set to 10.0


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          0
          • J Online
            J Online
            J.Hilk
            Moderators
            wrote on 5 Mar 2018, 06:46 last edited by
            #4

            Ok, I made some changes in my code. It sill doesn't show the E-Mail Popup but it no longer crashes.

            In the header file I changed

            @interface MyObject : NSObject
            {
            
            }
            
            //to
            @interface MyObject : UIViewController <MFMailComposeViewControllerDelegate>
            {
            
            }
            

            Aparently a NSOBject alone can not be the base of a ViewController?

            however now I run int this error or warning as nothing happens:

            Warning: Attempt to present <MFMailComposeViewController> on <MyObject> whose view is not in the window hierarchy!
            

            So, how would I make it a defined part of the window hierarchy, when the rest of the UI is made by Qt-Code?


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            0
            • J Online
              J Online
              J.Hilk
              Moderators
              wrote on 5 Mar 2018, 07:18 last edited by J.Hilk 3 May 2018, 07:22
              #5

              Never mind, @SGaist , I managed to make it work.

              //ObjectCInterface.h
              #ifndef __OBJECTIVECINTERFACE_H__
              #define __OBJECTIVECINTERFACE_H__
              
              class MyClassImpl
              {
              public:
                  MyClassImpl (void);
                  ~MyClassImpl (void);
              
                  void init (void);
              
                  void showEmail(char * aCstr);
              
              private:
                  void * self;
              };
              
              #endif
              
              //MyObject.h
              #import "ObjectCInterface.h"
              #import <Foundation/Foundation.h>
              #import <UIKit/UIKit.h>
              #import <MessageUI/MessageUI.h>
              
              @interface MyObject : UIViewController  <MFMailComposeViewControllerDelegate>
              {
              
              }
              
              - (void)showEmailPopup:(char *) aCStr;
              
              @end
              
              //MyObject.mm
              #import "MyObject.h"
              
              @implementation MyObject
              
              
              MyClassImpl::MyClassImpl( void ) : self(NULL){
                  init();
              }
              
              MyClassImpl::~MyClassImpl( void ){
                  [(id)self dealloc];
              }
              
              void MyClassImpl::init( void ){
                  self = [ [MyObject alloc] init];
              }
              
              
              void MyClassImpl::showEmail(char *aCstr){
                  NSLog(@"logMyMessage");
                  [(id)self showEmailPopup:aCstr];
              }
              
              
              - (void) showEmailPopup:(char *)aCStr{
                  NSLog(@"LogMyMessage in Obj");
                  NSLog([NSString stringWithUTF8String:aCStr]);
              
                  //Email Subject
                  NSString *emailTitle = @"Test Email";
                  
                  //Email Content
                  NSString *messageBody = @"ios programming is so fun!";
                  
                  //To Address
                  NSArray *toRecipents = [NSArray arrayWithObject:@"support@MyCompany.com"];
                  
                  MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
                  mc.mailComposeDelegate = self;
                  
                  [mc setSubject:emailTitle];
                  [mc setMessageBody:messageBody isHTML:false];
                  [mc setToRecipients:toRecipents];
                  
                  UIViewController * topController = [UIApplication sharedApplication].keyWindow.rootViewController;
                  while (topController.presentedViewController){
                      topController = topController.presentedViewController;
                  }
                  
                  [topController presentViewController:mc animated:YES completion:NULL];
              }
              
              
              - (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error{
                  switch (result) {
                      case MFMailComposeResultCancelled:
                          NSLog(@"Mail cancelled");
                          break;
                      case MFMailComposeResultSaved:
                          NSLog(@"Mail saved");break;
                      case MFMailComposeResultSent:
                          NSLog(@"Mail sent");break;
                      case MFMailComposeResultFailed:
                          NSLog(@"Mail sent failure: %@", [error localizedDescription]);
                          break;
                      default:
                          break;
                  }
                  
                  [controller dismissViewControllerAnimated:YES completion:NULL];
              }
              
              @end
              
              

              Now I'll have to find out how to add the MessageuiFramework to my *.pro file to compile it usccessfully in QtCreator . But thats an other topic I guess.


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SGaist
                Lifetime Qt Champion
                wrote on 5 Mar 2018, 07:35 last edited by
                #6
                ios {
                    LIBS += -framework MessageUI
                }
                

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1

                5/6

                5 Mar 2018, 07:18

                • Login

                • Login or register to search.
                5 out of 6
                • First post
                  5/6
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved