Swift: Load Photos images into app - ios

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)
}
}

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

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.

Related

Slow Response to Quick Succession Taps on UIButton & How to tap two buttons at once?

I've got a simple xylophone app I'm working with. When I try to tap a button several times in quick succession, a sound only plays for the first tap. Is there a way to decrease the response time required to play the sound?
Also, I'd like to be able to tap two or three buttons at once to play chords. How would I go about doing that?
I ran across this tutorial, is a UIGestureRecognizer the right approach?
Here's my code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func keyPressed(_ sender: UIButton) {
let soundName: String = sender.currentTitle!
sender.layer.removeAllAnimations()
playSound(note: soundName)
UIView.animate(withDuration: 0.2, delay: 0,
options: [],
animations: {
sender.alpha = 0.5
}, completion: { _ in
sender.alpha = 1
})
}
func playSound(note: String) {
let url = Bundle.main.url(forResource: note, withExtension: "wav")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
}
}

Swift: Using Volume Buttons does not work after returning from Background

I needed to write an iOS App which counts down by pressing the Up Volume Key on an iPhone or iPad. Therefore I used some advice from here to use AVAudioSession and observe the "outputVolume" key.
Here you can find the code of my ViewController:
import UIKit
import MediaPlayer
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
#IBOutlet weak var chickenLabel: UILabel!
let audioSession = AVAudioSession.sharedInstance()
var maxHendl:Int = 100
var istHendl:Int = 100
var isVolumeChanged = false
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
listenVolumeButton()
removeVolumeView()
}
func listenVolumeButton() {
do {
try audioSession.setActive(true)
}
catch {
print(error.localizedDescription)
}
audioSession.addObserver(self, forKeyPath: "outputVolume", options: .new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "outputVolume" {
if isVolumeChanged == false {
// Set Volume to 50%
MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(0.5, animated: false)
//do some Counting
}
}
}
func removeVolumeView() {
let volumeView: MPVolumeView = MPVolumeView(frame: CGRect.zero)
view.addSubview(volumeView)
}
}
Everything works as it should after starting the App for the first time. When I now press the Home Button and return back to the App the Events of pressing the volume buttons are not captured and the MPVolumeWindow is displayed again.
Can somebody help me to solve this issue?
Regards
Armin
When you come back from being in the background, your audio session is no longer active. You need to activate it again.

Swift image picker not working

I have look this code several times, even for hour now, but I can find error. :(
There is no error compiling project, no error showing at all, but I just can not pick image, when I press UIImage, nothing happened.
Have similar code in "signUp View Controller" when signing up everything goes well, you can choose (pick) image, and image is properly saved on Firebase.
Also, in this "ProfileTableViewController", everything is show very well, saved image on Firebase is loaded and shown inside Profile View, but can not pick it (press on it) to choose it and change.
Everything else is tested, changed and saved (username or even e-mail), only image gives me problem. Can you please look the code and tell me what I am doing wrong?
Thanks.
import UIKit
class ProfileTableViewController: UITableViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
#IBOutlet weak var profileImage: UIImageView!
#IBOutlet weak var username: UITextField!
#IBOutlet weak var email: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Edit Profile"
let tap = UITapGestureRecognizer(target: self, action: #selector(ProfileTableViewController.selectPhoto(_:)))
tap.numberOfTapsRequired = 1
profileImage.addGestureRecognizer(tap)
profileImage.layer.cornerRadius = profileImage.frame.size.height / 2
profileImage.clipsToBounds = true
if let user = DataService.dataService.currentUser {
username.text = user.displayName
email.text = user.email
if user.photoURL != nil {
if let data = NSData(contentsOfURL: user.photoURL!) {
self.profileImage!.image = UIImage.init(data: data)
}
}
} else {
// No user is signed in
}
}
func selectPhoto(tap: UITapGestureRecognizer) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
imagePicker.sourceType = .Camera
} else {
imagePicker.sourceType = .PhotoLibrary
}
self.presentViewController(imagePicker, animated: true, completion: nil)
}
// UIImagePicker Delegate
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
profileImage.image = image
dismissViewControllerAnimated(true, completion: nil)
}
You need to enable user interaction on the UIImageView, try this after adding gesture recognizer:
profileImage.userInteractionEnabled = true
I did it Other way by Checking User Interaction Enabled under "Interaction" option, see below image for reference
Hope it help anybody

Why is my data is not writing to Firebase - App crashes due to setObjectForKey: key cannot be nil

for the past two weeks i've been having a struggle to write data to firebase, although the tutorials seem so simple :/....My app has a view controller and a tableview controller. users can add an event Title, event date and description (strings) and add a picture as well. Whenever i try to run the simulator it crashes on me! See code below. Please please help me out this is really getting frustrating.. Even if I place breakpoints in the code on top it crashes.. If someone can help me in a chat that would be awesome or maybe send the file to cause its been too long seriously I need an answer so i understand the problem.
import UIKit
import Firebase
import FirebaseDatabaseUI
class EventViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//outlets for text & image
#IBOutlet weak var photoImageView: UIImageView!
#IBOutlet weak var eventName: UITextField!
#IBOutlet weak var eventDate: UITextField!
#IBOutlet weak var eventDes: UITextView!
//Database connection
let rootref = FIRDatabase().reference()
var imagePicker: UIImagePickerController = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func submitEvent(sender: AnyObject) {
let name = eventName.text
let date = eventDate.text
let text = eventDes.text
var data: NSData = NSData()
var user = NSDictionary()//declare here
if let image = photoImageView.image {
data = UIImageJPEGRepresentation(image,0.1)!
}
let base64String = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
if let unwrappedName = name , unwrappedDate = date, unwrappedText = text{
//use your declared dictionary
user = ["name":unwrappedName, "date":unwrappedDate, "text":unwrappedText, "photoBase64":base64String]
}
//Add firebase child node
//let event = FIRDatabase().reference().child(name!)
//Do not create one more reference to database
rootref.child(name!)
rootref.child(name!).setValue(user)
navigationController?.popViewControllerAnimated(true)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}
//UIImagePickerControllerDelegate methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imagePicker.dismissViewControllerAnimated(true, completion: nil)
photoImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func addPicture(sender: AnyObject) {
if(UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)) {
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .Camera
presentViewController(imagePicker, animated: true, completion: nil)
} else {
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
imagePicker.delegate = self
presentViewController(imagePicker, animated: true, completion:nil)
}
}
}

Facebook signup uses wrong segue within if statement - Swift

So on my first screen of my iOS app I have a “Login” “SignUp” and a “SignUp With Facebook” buttons. The first two buttons link to their own view controllers just fine, and once logged in the simulator will automatically log them in with the:
if PFUser.currentUser() != nil {
self.performSegueWithIdentifier("autoSegue", sender: self)
} else {
Code that you can see at the bottom of the full block of code below. However the Facebook signup I want to transition to a separate view controller where I can show them their profile pic, capture the data on Parse, have them enter a user name, then segue to the same view controller that the SignUp and Login go to – autoSegue. I have all the code on that view controller already written out, but my problem is that when they click the signup button for Facebook, it takes them through the autoSegue and not the fbSignup segue (the one that links to where I want to capture the FB data). Both segues are linked directly from the view controller (not the buttons themselves), and I receive no build errors. I appreciate any help.
Thanks!
Full code:
import UIKit
import Parse
import MediaPlayer
import FBSDKCoreKit
class ViewController: UIViewController {
#IBOutlet var loginAlpha: UIButton!
#IBOutlet var signupAlpha: UIButton!
var avPlayer: AVPlayer!
var avPlayerLayer: AVPlayerLayer!
var paused: Bool = false
#IBAction func facebookSignup(sender: AnyObject) {
let permissions = ["public_profile"]
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissions) { (user: PFUser?, error: NSError?) -> Void in
if let error = error {
print(error)
} else {
if let user = user {
self.performSegueWithIdentifier("fbSignup", sender: self)
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// code for background video
let theURL = NSBundle.mainBundle().URLForResource("test", withExtension: "mp4")
avPlayer = AVPlayer(URL: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
avPlayer.volume = 0
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEnd.None
avPlayerLayer.frame = view.layer.bounds
view.backgroundColor = UIColor.clearColor();
view.layer.insertSublayer(avPlayerLayer, atIndex: 0)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "playerItemDidReachEnd:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: avPlayer.currentItem)
}
func playerItemDidReachEnd(notification: NSNotification) {
let p: AVPlayerItem = notification.object as! AVPlayerItem
p.seekToTime(kCMTimeZero)
}
override func viewDidAppear(animated: Bool) {
if PFUser.currentUser() != nil {
self.performSegueWithIdentifier("autoSegue", sender: self)
} else {
signupAlpha.alpha = 0
loginAlpha.alpha = 0
UIView.animateWithDuration(1.5, delay: 1.0, options: [], animations: { () -> Void in
self.signupAlpha.alpha = 1.0
self.loginAlpha.alpha = 1.0
}, completion: nil)
avPlayer.play()
paused = false
}
}
override func viewDidDisappear(animated: Bool) {
avPlayer.pause()
paused = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You are using Storyboards? You may have messed up on the storyboard and connected the segue to the wrong ViewController.
I can't see anything particularly wrong with your code.

Resources