Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share extension with custom class instead of SLComposeServiceViewController

I'm currently working with share extension feature.

here when I search lot, seems always using SLComposeServiceViewController to share the image with some text content to particular app.

But I'm expect custom UIViewController class loaded with selected image from photos app where ever it is like same as the mail composer when open mail extension on share sheet

So I got this sample and I followed the instructions which is on this source from the below git hub link (2nd one):

  • https://martinnormark.com/present-ios-8-share-extension-as-modal-view/
  • https://github.com/martinnormark/ShareByMail

Yes it's seems 4 years ago so migration and converted to Swift 4.1 version. After I modified those changes and debug it. It's not working like on the GitHub gif. Yes when initial time, I can present and dismiss a controller when I touch extension app on share sheet. But after I dismissed and again tried to present it, this time it's not reacted on the GitHub gif.

Martin only show and hide the self.view of UINavigationController Y position value. Once I pressed the Cancel or save bar buttons, then I tried to open it touch by extension on share sheet, it's not working and no reaction there.

Here is the source for NSExtensionPrincipalClass - EntryViewController

import UIKit  

@objc(EntryViewController)


class EntryViewController : UINavigationController {

init() {
    super.init(rootViewController: ShareViewController())
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
}

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.view.transform = CGAffineTransform(translationX: 0, y: self.view.frame.size.height)

    UIView.animate(withDuration: 0.25, animations: { () -> Void in
        self.view.transform = CGAffineTransform.identity
    }, completion: nil)
}
}

import UIKit
import Social

class ShareViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.backgroundColor = .white
    self.navigationItem.title = "Share this"

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancelButtonTapped(_:)))
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(self.saveButtonTapped(_:)))
}

@objc func saveButtonTapped(_ sender: UIBarButtonItem) {
    self.hideExtensionWithCompletionHandler(completion: { (Bool) -> Void in
        self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil)
    })
}

@objc func cancelButtonTapped(_ sender: UIBarButtonItem) {
    self.hideExtensionWithCompletionHandler(completion: { (Bool) -> Void in
        self.extensionContext!.cancelRequest(withError: NSError())
    })
}

func hideExtensionWithCompletionHandler(completion:(Bool) -> Void) {

    UIView.animate(withDuration: 0.20, animations: { () -> Void in
        self.navigationController!.view.transform = CGAffineTransform(translationX: 0, y: self.navigationController!.view.frame.size.height)
    }, completion: nil)
}
}

How to find and fix issues on the above attempt or how to do custom UIViewController layout instead of using SLComposeServiceViewController?

like image 320
Ram Avatar asked Nov 08 '22 04:11

Ram


1 Answers

On your view controller (Button action method)

Objective C

Call this when you complete your process

[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];

Call this when you/user cancel your process

NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil];
[self.extensionContext cancelRequestWithError:error];

Swift

Call this when you complete your process

self.extensionContext?.completeRequestReturningItems([], completionHandler:nil)

Call this when you/user cancel your process

let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)
self.extensionContext!.cancelRequestWithError(cancelError)

If you have any API error

self.extensionContext!.cancelRequestWithError(error as NSError)

Update

On your code, you didn't call the completion handler at this method hideExtensionWithCompletionHandler

func hideExtensionWithCompletionHandler(completion:@escaping (Bool) -> Void) {
    UIView.animate(withDuration: 0.20, animations: { () -> Void in
        self.navigationController!.view.transform = CGAffineTransform(translationX: 0, y: self.navigationController!.view.frame.size.height)
    }, completion: { (_) -> Void in
        completion(true)
    })
}
like image 164
Mathi Arasan Avatar answered Nov 14 '22 22:11

Mathi Arasan