0

I have an app which shows a screensaver when it detects that there is no user action. Currently, it is working as the images for the screensaver are preloaded into the app.

But ultimately I want the screensaver to access and show the images inside Photos as we would save promotion images into Photos and these images are subjected to frequent changes.

I am stuck and do not know how to proceed to access and read images from Photos.

Please help. :(

import UIKit
import Photos

class ScreenSaverViewController: UIViewController {
    @IBOutlet weak var ssImage: UIImageView!

    var timer = Timer()
    var count = 0

    var arrayPhoto: [UIImage] = [
        UIImage(named:"0.jpg")!,
        UIImage(named:"1.jpg")!,
        UIImage(named:"2.jpg")!,
        UIImage(named:"3.jpg")!
    ]

    var images = [PHAsset]()

    func nextImage() {
         let currentIndex = arrayPhoto.index(of: ssImage.image ?? UIImage()) ?? -1

         var nextIndex = currentIndex + 1

         nextIndex = arrayPhoto.indices.contains(nextIndex) ? nextIndex : 0

         UIView.transition(with: ssImage, duration: 0.5, options: .transitionCrossDissolve, animations: { self.ssImage.image = self.arrayPhoto[nextIndex] }, completion: nil)


    }

    func scheduledTimer(){
         timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: (#selector(nextImage)), userInfo: nil, repeats: true)
         count = 1
    }

    override func viewDidLoad() {
         super.viewDidLoad()
         if count == 0 {
              ssImage.image = UIImage(named: "0.jpg")
         }
         scheduledTimer()
    }

    override func didReceiveMemoryWarning() {
         super.didReceiveMemoryWarning()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         timer.invalidate()
         self.dismiss(animated: true, completed: nil)
    }

}
Spiral1ng
  • 313
  • 1
  • 7
  • 16

2 Answers2

2

You can directly use Photos framework. I encourage you to read documentation first: https://developer.apple.com/documentation/photos

Anyway, to get images, you can do it like this:

func getImages() {
    let assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: nil)
    assets.enumerateObjects({ (object, count, stop) in
        self.images.append(object)
    })

    //In order to get latest image first, we just reverse the array
    images.reverse() 
}

Credits: Swift 3: Load photos from Photos/Camera Roll without using UIImagePickerController

Anton Malmygin
  • 3,406
  • 2
  • 25
  • 31
  • Thanks. How do I then transit to the next image as previously I was calling arrayPhoto.index(of: ssImage.image ?? UIImage()) ?? -1 where arrayPhoto was the declaration of the images preloaded. – Spiral1ng Jan 18 '18 at 09:41
  • @Spiral1ng Keep track of current `PHAsset` shown and when apply the same logic as before to get next one. – Anton Malmygin Jan 18 '18 at 09:56
0

I think you should provide a button in your app, tapping on which will open UIImagePickerController with source type .photos. The user of the app can select the images he wish should be included in the screen saver.

Implement the protocols UIImagePickerController & UINavigationControllerDelegate, particularly the function func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) in which you can access the selected images. You may then save these images to the Documents folder of your app and use them while showing the screen saver.

Yogi
  • 3,578
  • 3
  • 35
  • 56
  • I want to have zero user intervention as the previous app using swift 2 was built this way, but the ALAssetsLibrary has since deprecated. – Spiral1ng Jan 18 '18 at 09:22
  • Apple is not a very big supporter of giving the user's personal stuff's access to the developer without the user's permission. So I think you will have to ask the user before using his images as screensaver. This might be the reason behind deprecating ALAssetsLibrary. – Yogi Jan 18 '18 at 13:34