filestack / filestack-ios

Official iOS SDK for Filestack - API and content management system that makes it easy to add powerful file uploading and transformation capabilities to any web or mobile application.
https://www.filestack.com
MIT License
54 stars 36 forks source link

Upload works, but PickerNavigationControllerDelegate handlers doesn't work. #62

Closed MherKarapetyan closed 4 years ago

MherKarapetyan commented 5 years ago

picker.pickerDelegate = self in ViewController

extension ViewController: PickerNavigationControllerDelegate {
    func pickerUploadedFiles(picker _: PickerNavigationController, responses _: [NetworkJSONResponse]) {
        print("Picker Uploaded Files")
    }
    func pickerStoredFile(picker _: PickerNavigationController, response: StoreResponse) {
            print("Stored file response:")
    }
    func pickerReportedUploadProgress(picker: PickerNavigationController, progress: Float) {
        print("Picker \(picker) reported upload progress: \(progress)")
    }
}
MherKarapetyan commented 4 years ago

@rnin Pay attention on this issue as soon as possible.

rnine commented 4 years ago

@MherKarapetyan Sorry, I am unable to reproduce this issue locally using the demo project. Could you provide some further details?

  1. Version of FilestackSDK used.
  2. Upload source used (e.g. Camera, Photo Library, iOS Files, Dropbox, Custom, etc.).
  3. Xcode version and iOS version used on device or simulator.
  4. Anything else that could help reproduce the issue (e.g. link to Github repo showcasing the problem — just make sure any sensitive info like API/secret keys are removed.)

Thanks!

MherKarapetyan commented 4 years ago

@rnine Thank you for response.

    • FilestackSDK (~> 2.2)
    • Filestack (~> 2.2)
    • CryptoSwift (= 1.0)
    • Alamofire (~> 4.9)
    • SSZipArchive (= 2.2.2)
    • SVProgressHUD (~> 2.2)
  1. [.dropbox, .googleDrive, .facebook, .instagram, .googlePhotos, .oneDrive, .amazonDrive, .photoLibrary, .documents]

  2. Xcode 11.1, devices: IOS 13.1.3, IOS 12.3.1, simulator: IOS 13.1

NOTE. We try to integrate Filestack SDK to Flutter for both in IOS and Android. In IOS side everything works, I see upload in filestack, but handlers doesn't work. I try to hardcoded call pickerReportedUploadProgress function, and it works.

import Filestack
import FilestackSDK
import Flutter
import Foundation
import UIKit

public class SwiftFilestackFlutterPlugin: NSObject, FlutterPlugin {
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "filestack_flutter", binaryMessenger: registrar.messenger())
        let instance = SwiftFilestackFlutterPlugin()

        registrar.addMethodCallDelegate(instance, channel: channel)
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        if call.method == "launchFilestack" {
            let viewController = ViewController()
            let data = call.arguments as! [String: Any]
            viewController.openPicker(result: result, data: data)
        }
    }
}

class ViewController: UIViewController {
    override func present(_ viewControllerToPresent: UIViewController, animated _: Bool, completion: (() -> Void)? = nil) {
        if let viewController = viewControllerToPresent as? PickerNavigationController {
            viewController.modalPresentationStyle = .pageSheet
        }
        super.present(viewControllerToPresent, animated: true, completion: completion)
    }

    public func openPicker(result _: FlutterResult, data: [String: Any]) {
        let encodedPolicy: String = data["policy"] as! String
        let signature: String = data["signature"] as! String
        let security = Security(encodedPolicy: encodedPolicy, signature: signature)
        var nsDictionary: NSDictionary?
        if let path = Bundle.main.path(forResource: "Info", ofType: "plist") {
            nsDictionary = NSDictionary(contentsOfFile: path)
        }

        var callbackURLScheme: String = data["callbackURLScheme"]

        let config = Filestack.Config.builder
            .with(callbackURLScheme: callbackURLScheme)
            .with(videoQuality: .typeHigh)
            .with(imageURLExportPreset: .compatible)
            .with(maximumSelectionLimit: 5)
            .withEditorEnabled()
            .with(availableCloudSources: [.dropbox, .googleDrive, .facebook, .instagram, .googlePhotos, .oneDrive, .amazonDrive])
            .with(availableLocalSources: [.photoLibrary, .documents])
            .build()

        let apiKey: String = nsDictionary?.object(forKey: "FilestackApiKey") as? String ?? "";

        let client = Filestack.Client(apiKey: apiKey, security: security, config: config)

        let storeOptions = StorageOptions(location: .s3, access: .public)

        let picker = client.picker(storeOptions: storeOptions)

        picker.pickerDelegate = self

        let rootViewController = UIApplication.shared.keyWindow?.rootViewController

        rootViewController?.present(picker, animated: true)
    }
}

extension ViewController: PickerNavigationControllerDelegate {
    func pickerUploadedFiles(picker _: PickerNavigationController, responses _: [NetworkJSONResponse]) {
        print("Stored file response")
    }

    func pickerStoredFile(picker _: PickerNavigationController, response: StoreResponse) {
        print("Stored file response:")
    }

    func pickerReportedUploadProgress(picker: PickerNavigationController, progress: Float) {
        print("Picker \(picker) reported upload progress: \(progress)")
    }
}
rnine commented 4 years ago

@MherKarapetyan Yeah, I see your problem. Your ViewController is being deallocated after the picker is presented by your rootViewController since it is not strongly retained by anything. Keep in mind that pickerDelegate only holds a weak reference to it (best practice for delegates.)

Using a UIViewController as your picker's delegate is not really necessary, specially if you are not going to be using it for anything (e.g. to present the picker.) You could use any other object. Just make sure the object you end up using as your picker's delegate is strongly retained by something else.

Hope this makes sense!

MherKarapetyan commented 4 years ago

@rnine Thanks a lot. The mistake was mine.

rnine commented 4 years ago

@MherKarapetyan No worries! Glad to help! Closing this issue.