I need to import to my app some document that have been saved into the "On My iPhone" folder. What would be the url of this folder? (those document (pdf) are saved outside the app by the user and I would like if possible to move/copy them to the app document folder but again I can't find that url.
Try this code (the way to pick needed document from iPhone Folder:
extension YourViewController: UIDocumentInteractionControllerDelegate {
/// If presenting a top a navigation stack, provide the navigation controller in order to animate in a manner consistent with the rest of the platform
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self.navigationController ?? self
}
}
extension YourViewController : UIDocumentPickerDelegate {
func initDocs() {
let pickerController = UIDocumentPickerViewController(documentTypes: ["public.item"], in: .import)
pickerController.delegate = self
if #available(iOS 11.0, *) {
pickerController.allowsMultipleSelection = false
}
present(pickerController, animated: false, completion: nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
if let url = urls.first {
self.handleDoc(url: url) // method in your view controller
}
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
print("url = \(url)")
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
dismiss(animated: true, completion: nil)
}
}
In YourViewController call function:
#IBAction func importPem(_ sender: UIButton) {
initDocs()
UIDocumentInteractionController().presentPreview(animated: true)
}
Related
I am new into this Xcode iOS stuff, I am trying to build a file uploader, you pick a file and then you upload to server. Currently I am stuck at picking the file. I have used some code found on this website, but I am getting some errors.
Class starts like this:
class DocumentsController: UIViewController, UIDocumentMenuDelegate,UIDocumentPickerDelegate,UINavigationControllerDelegate
Methods used are:
#objc func pickFile() {
let importMenu = UIDocumentMenuViewController(documentTypes: [String(kUTTypePDF), String(kUTTypePNG), String(kUTTypeJPEG)], in: .import)
importMenu.delegate = self
importMenu.modalPresentationStyle = .formSheet
self.present(importMenu, animated: true, completion: nil)
}
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let myURL = urls.first else {
return
}
print("import result : \(myURL)")
}
public func documentMenu(_ documentMenu:UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print("view was cancelled")
dismiss(animated: true, completion: nil)
}
In the documentPicker method I have two errors:
'URL' is ambiguous for type lookup in this context <- for urls: [URL]
Type of expression is ambiguous without more context <- for guard let myURL = urls.first
If I replace URL with String or NSURL it gets past that, the build is successful, the app on the simulator is running (Iphone 8 plus), I can open the picker, choose a file, but then nothing happens. It just closes the picker and that's it. documentPicker method doesn't trigger. Out of the 4 methods only pickFile and documentMenu are triggering.
Xcode version is 13.3.1
I'm using UIDocumentPickerViewController to select a document from the iPhone.
I have implemented the feature in the following way.
class Si3EntityDocumentViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIDocumentInteractionControllerDelegate, UIDocumentPickerDelegate, UINavigationControllerDelegate, UIDocumentMenuDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setLoader()
getDocuments(id:entity.id)
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = .red
button.setTitle("Upload Doc", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
// Do any additional setup after loading the view.
}
#objc func buttonAction(sender: UIButton!){
let documentPicker = UIDocumentPickerViewController(documentTypes: [String(kUTTypeText),String(kUTTypeContent),String(kUTTypeItem),String(kUTTypeData)], in: .import)
documentPicker.delegate = self
present(documentPicker, animated: true, completion: {
documentPicker.delegate = self
} )
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
print(urls)
}
}
The func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt url: URL) method has been deprecated in iOS 11 so i have replaced it with func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])
For some reason, I'm not getting the callback in func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])
I also have some other code in this class but I've not included it.
When I select a document or click cancel I get the following error in the console
[DocumentManager] The view service did terminate with error: Error
Domain=_UIViewServiceErrorDomain Code=1 "(null)"
UserInfo={Terminated=disconnect method}
I know I'm missing out something very silly, any help is appreciated.
Thanks in anticipation.
You can have a look at the Apple documentation for a better understanding.
The default behaviour of a UIDocumentPickerViewController is to pick one document and you would have to use:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
}
If you are using the UIDocumentPickerViewController to pick multiple documents, then you will have to set the allowsMultipleSelection property to true and implement
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
}
Also, the following line would suffice.
present(documentPicker, animated: true)
I Used this Methods in swift 3
func openImportDocumentPicker() {
let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.item"], in: .import)
documentPicker.delegate = self
documentPicker.modalPresentationStyle = .formSheet
self.present(documentPicker, animated: true, completion: { _ in })
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
if controller.documentPickerMode == .import {
let alertMessage: String = "Successfully imported \(url.absoluteURL)"
}
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print("Cancelled")
}
Try on a device. Simulator wasn't working for me when I logged into iCloud and tried to view a directory.
I have integrated UIDocumentPickerDelegate or UIDocumentMenuDelegate, I have an issue to get the file from URL or DocumentPicker. How can I solve this issue in iOS swift?
You can get file easily like,
If you need to get image
#IBAction func btn_Handler_iCloud(_ sender: Any) {
let doc = UIDocumentMenuViewController(documentTypes: [String(kUTTypeImage)], in: .import)
doc.delegate = self
doc.modalPresentationStyle = .formSheet
self.present(doc, animated: true, completion: nil)
}
func documentMenu(_ documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
let data = try! Data(contentsOf: urls[0])
imageview_Buaty.image = UIImage.init(data: data)
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
dismiss(animated: true, completion: nil)
}
Getting document URL or data from UIDocumentPickerViewController:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
// Available from iOS 8.0 to iOS 11.0
self.handleFileSelection(inUrl: url)// Here url is document's URL
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
// Available from iOS 11.0
self.handleFileSelection(inUrl: urls.first!) // Here urls is array of URLs
}
private func handleFileSelection(inUrl:URL) -> Void {
do {
// inUrl is the document's URL
let data = try Data(contentsOf: inUrl) // Getting file data here
} catch {
dLog(message: "document loading error")
}
}
I have implemented UIDocumentPickerViewController in my class.implemented delegate methods.
I want to know how would I know which option from documentPickerMenu i have selected. I want to implement the dropbox selection in the presented menu of document controller. I want to know it from delegate method.
the methods are as below
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
let cico = url as URL
print("The Url is : \(cico)")
}
func documentMenu(_ documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
print(documentMenu.accessibilityLabel ?? "Menu")
present(documentPicker, animated: true, completion: nil)
}
func documentMenuWasCancelled(_ documentMenu: UIDocumentMenuViewController) {
print("we cancelled")
dismiss(animated: true, completion: nil)
}
if anyone can help me thanks in advance.
I have an app that is currently using a webview and when certain links are clicked in the webview, it opens those links in Safari. I now want to implement the Safari View Controller(SVC) instead of booting it to the Safari app. I have done research and looked at examples on the SVC; however, all I see are ones that open the SVC from the click of a button. Does anyone have any suggestions for me to look at or to try?
Here is some of my code:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
let host = request.URL!.host!;
if (host != "www.example.com"){
return true
} else {
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}
func showLinksClicked() {
let safariVC = SFSafariViewController(URL: NSURL(string: "www.example.com")!)
self.presentViewController(safariVC, animated: true, completion: nil)
safariVC.delegate = self }
func safariViewControllerDidFinish(controller: SFSafariViewController) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
If I am understanding correctly you are loading a page on webview which has certain links now when user clicks on link you want to open those page in SVC. You can detect link click in webview using following delegate method and then open SVC from there.
EDIT
Based on edited question I can see that you are not calling showLinksClicked func , you can call this function as I have updated in following code and it should work.
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
self.showLinksClicked()
return false
}
return true;
}
func showLinksClicked() {
let safariVC = SFSafariViewController(url: URL(string: "www.google.com")!)
present(safariVC, animated: true, completion: nil)
safariVC.delegate = self
}
func safariViewControllerDidFinish(controller: SFSafariViewController) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
For Swift 3:
First, import SafariServices and integrate the delegate into your class:
import SafariServices
class YourViewController: SFSafariViewControllerDelegate {
Then, to open Safari with the specified url:
let url = URL(string: "http://www,google.com")!
let controller = SFSafariViewController(url: url)
self.present(controller, animated: true, completion: nil)
controller.delegate = self
And now you can implement the delegate callback to dismiss safari when the user is finished:
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
This piece of code will allow you to do this.
let safariVC = SFSafariViewController(URL: NSURL(string: "https://www.google.co.uk")!)
self.presentViewController(safariVC, animated: true, completion: nil)
safariVC.delegate = self
You may need to add this to the top of the class as well:
import SafariServices
Solution For Swift 4
Step 1:
import Safari Service In you Class
import SafariServices
Step 2:
Import SFSafariViewControllerDelegate in With your View Controller
class ViewController: UIViewController,SFSafariViewControllerDelegate {...}
Step 3:
Create A function to Open Safari View Controller.
func openSafariVC() {
let safariVC = SFSafariViewController(url: NSURL(string: "https://www.google.com")! as URL)
self.present(safariVC, animated: true, completion: nil)
safariVC.delegate = self
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
Step 4:
call the function openSafariVC
openSafariVC()
Note: Don't forget To Add Navigation Controller with your View
Controller.
Now your SafariVC is ready to open your Link within an app without Using UIWebView Oe WKWebView
Follow the steps :
On your controller file(e.g. ViewController.swift) import SafarriServices.
import SafariServices
Then where you want to open link write
let controller = SFSafariViewController(URL: NSURL(string: "https://www.google.co.uk")!)
self.presentViewController(controller, animated: true, completion: nil)
controller = self
Swift 4.2
This is how you can open-up Safari browser within your application.
import SafariServices
whenever you want to open, like wise on
#IBAction func btnOpenWebTapped(_ sender: UIButton) {
self.openWeb(contentLink: "https://www.google.com")
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.openWeb(contentLink: "https://www.google.com")
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.openWeb(contentLink: "https://www.google.com")
}
by write the custom function be like and you can customise the properties of the SFSafariViewController, preferredBarTintColor, preferredControlTintColor, dismissButtonStyle, barCollapsingEnabled
func openWeb(contentLink : String){
let url = URL(string: contentLink)!
let controller = SFSafariViewController(url: url)
controller.preferredBarTintColor = UIColor.darkGray
controller.preferredControlTintColor = UIColor.groupTableViewBackground
controller.dismissButtonStyle = .close
controller.configuration.barCollapsingEnabled = true
self.present(controller, animated: true, completion: nil)
controller.delegate = self
}
last and the most important thing is don't forget to bind the delegate of the SFSafariViewController with your view controller. you can do this by below mentioned extension code.
extension YourViewController: SFSafariViewControllerDelegate
{
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
Happy coding Thank you :)
import SafariServices
class ViewController: UIViewController, SFSafariViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let url = URL(string: "http://www.google.com")!
let controller = SFSafariViewController(url: url)
self.present(controller, animated: true, completion: nil)
controller.delegate = self
}
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
dismiss(animated: true)
}
}