How to access photos from actual device using UIImagePickerController - ios

Currently I am using this code:
#IBAction func selectPicture(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
var imag = UIImagePickerController()
imag.delegate = self
imag.sourceType = .Camera;
imag.mediaTypes = [kUTTypeImage as String]
imag.allowsEditing = false
imag.modalPresentationStyle = .Popover
self.presentViewController(imag, animated: true, completion: nil)
}
}
But when I run it on the iPad of iPhone device it asks me only for the camera permission and I don't have the possibility to choose a photo from any album/camera roll.
What can I do so I can access the photos from the device ?

You are setting the wrong sourceType:
imag.sourceType = .Camera;
Change that to:
imag.sourceType = .SavedPhotosAlbum;
or
imag.sourceType = .PhotoLibrary
The constants are defined in UIImagePickerControllerSourceType Enumeration and the definition is like:
UIImagePickerControllerSourceType
The source to use when picking an image or when determining available
media types. Declaration
Swift
enum UIImagePickerControllerSourceType : Int
{
case PhotoLibrary
case Camera
case SavedPhotosAlbum
}
Constants
PhotoLibrary
Specifies the device’s photo library as the source for the image picker controller.
Camera
Specifies the device’s built-in camera as the source for the image picker controller. Indicate the specific camera you want (front or
rear, as available) by using the cameraDevice property.
SavedPhotosAlbum
Specifies the device’s Camera Roll album as the source for the image picker controller. If the device does not have a camera,
specifies the Saved Photos album as the source.
Discussion
A given source may not be available on a given device because the
source is not physically present or because it cannot currently be
accessed.

Related

PHPickerViewController load videos via PHAsset

PHPickerViewController allows access to copies of photo library assets as well as returning PHAssets in the results. To get PHAssets instead of file copies, I do:
let photolibrary = PHPhotoLibrary.shared()
var configuration = PHPickerConfiguration(photoLibrary: photolibrary)
configuration.filter = .videos
configuration.selectionLimit = 0
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
self.present(picker, animated: true, completion: nil)
And then,
//MARK:- PHPickerViewController delegate
#available(iOS 14, *)
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true) {
let identifiers:[String] = results.compactMap(\.assetIdentifier)
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
NSLog("\(identifiers), \(fetchResult)")
}
}
But the problem is once the photo picker is dismissed, it prompts for Photo Library access which is confusing and since the user anyways implicitly gave access to the selected assets in PHPickerViewController, PHPhotoLibrary should load those assets directly. Is there anyway to avoid the Photo library permission?
Is there anyway to avoid the Photo library permission?
Yes, sort of:
Change PHPickerConfiguration(photoLibrary: photolibrary) to PHPickerConfiguration()
Do not use the assetIdentifier to return to the photo library (it will be nil anyway)
In that case, the user can give you image data but that's all. The picker is out-of-process and no data from the library itself is really coming across, just a mere image that the user has explicitly selected.
However, if your goal really is to return to the photo library and obtain the PHAsset, then you must have permission, as you now are indeed attempting to probe the photo library behind the scenes within your app.
What I do, when my app depends on PHAsset information, is to ask for photo library permission (if needed) before presenting the picker, and I don't present the picker if I can't get permission. So, the user taps a button, I discover we have no permission, I ask for permission, we get it (let's say), and I present the picker (doing the asynchronous dance, because the permission arrives asynchronously). Looks great.
By the way, this is also just as true with UIImagePickerController.

Camera Option Change

I am coding with Swift to develop a Video Camera App. In order to do it, I am using UiimagePickercontroller. But since the key feature of my app is a video camera but a photo camera, I would like to switch the order of "Photo" and "Video" on my app. But when it runs, the "Photo" is always selected first. I just want the "Video" to be selected first, and then if users want to use the "Photo", they swipe to change it. See the screenshot below.
Screenshot Here
If the key feature of your app is video camera then present only video camera, why you present both. If you do below you will get only video camera:
let imagepickerController = UIImagePickerController()
imagepickerController.sourceType = .camera
imagepickerController.mediaTypes = ["public.movie"]
imagepickerController.delegate = self
self.present(imagepickerController, animated: true, completion: nil)
If you include "public.image" in the imagepickerController.mediaTypes then it will give system default controls by default selecting photo and this seems to be non-configurable.

Image from iPhone photo library is scaled down when picked

I'm trying to implement a little tool to manipulate photos on the iPhone. I'm currently using both the simulator and an iPhone 7 with iOS 13.5.1.
I've noticed that when I copy a photo from the Mac to the simulator or via iCloud to the device, the dimensions after picking it in my app differ a lot from what the macOS Photos app tells me they should be.
Example:
Panorama in macOS Photos with dimensions of 14204 × 3628 pixels is exported as original version. Finder shows the same dimensions.
Image file copied to simulator via drag & drop and opened by my app with UIImagePickerController: 2048 x 523 pixels.
Panorama copied to device via iCloud and opened by my app with UIImagePickerController: 4096 x 1046
I'd actually like to open the image with its real dimensions as shown in Finder and Photos. I'm currently using the following code:
#IBAction func btnAddProjectPressed(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.dismiss(animated: true, completion: { () -> Void in
})
pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
imageView.image = image
}
UPDATE:
I've managed to get the unscaled image using the .phAsset value from the info dictionary, loading the "real" image using the PHImageManager. However, this outputs the message
Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)"
This problem is described in many questions here (for example this one) and I could not really find a solution. Even Apple's sample project outputs this error and doesn't show any photos or albums.
However, combining the UIImagePickerController and the PHImageManager seems to reduce this to a warning so that I do get the full-sized image.

How to access music files stored on the iOS device?

My application is having trouble locating the files that are in the music folder on my iOS device.
If the files are held below as application data (in my playpen), no problem. But when I go looking for the "Music" folder, using the following lines:
dest_dir = try! FileManager.default.url(for: .musicDirectory, in: .allDomainsMask, appropriateFor: nil, create: false)
musicDir = dest_dir
if UIApplication.shared.canOpenURL(musicDir) {
print("found music directory")
}else {
print("did not find music directory")
}
When the code executes the canOpenURL, I get a permissions complaint.
I also tried accessing the user directory (thinking I could then navigate into Music).
Any clues on how an application can access the files and playlists held under the music system folder on the iOS device?
There is no such thing as "the Music folder" in iOS. To access the user's music library, use the Media Player framework.
Example (assuming you have obtained the necessary authorization from the user):
let query = MPMediaQuery()
let result = query.items
Here you go! (Swift 4.2)
Inside a button method or #IBAction button
let mediaItems = MPMediaQuery.songs().items
let mediaCollection = MPMediaItemCollection(items: mediaItems ?? [])
let player = MPMusicPlayerController.systemMusicPlayer
player.setQueue(with: mediaCollection)
player.play()
let picker = MPMediaPickerController(mediaTypes: .anyAudio)
picker.delegate = self
picker.allowsPickingMultipleItems = false
picker.prompt = "Choose a song"
present(picker, animated: true, completion: nil)
iOS doesn’t give you direct access to the Music folder, for security and privacy reasons; you need to use the APIs in the MediaPlayer framework. Assuming you’re trying to play content from the user’s library, take a look at MPMusicPlayerController; you’ll need to provide it some MPMediaItem instances retrieved with an MPMediaQuery, then call methods from the MPMediaPlayback protocol on the controller to make it play the content.

How do i select multiple (2-5) images for an Image picker then return as image view?

Hey so I'm trying to have a button that when pressed allows the user to choose 2-5 pictures from their photo library then have whatever photo chosen be set onto a uiimageview? I was looking online and couldn't find anything related to how to do it in swift?
Thanks
I worked out using this : https://github.com/zhangao0086/DKImagePickerController .
Getting selected image's thumbnail images:
let pickerController = DKImagePickerController()
pickerController.sourceType = .Photo
pickerController.didCancelled = { () in
println("didCancelled")
}
pickerController.didSelectedAssets = { [unowned self] (assets: [DKAsset]) in
println("didSelectedAssets")
println(assets)
for(var i = 0; i<(assets.count); i++){
print(assets[i].url)
self.PickedArray .addObject(assets[i].thumbnailImage!)
}
self.performSegueWithIdentifier("SegueToPhotoLibraryView", sender: self)
Getting selected image's urls :
assets[i].url instead of assets[i].thumbnailImage
Hope it helps!
Currently iOS does not provide an image picker out of the box that lets you pick multiple images from the photo library. UIImagePickerController only lets you select one image.
But there are several image picker implementations available that let you pick multiple images. You can find a whole bunch at cocoacontrols.com as #ytbryan already mentioned.
I am currently not aware of any multiple image picker implemented in Swift. If someone finds one, please edit and post the link.

Resources