how change a piece of Url with Textbox & Button?(Swift 2) - ios

this is my code but its give me nil in output.
import AVFoundation
import AVKit
import UIKit
var userName :String?
class ViewController: UIViewController {
var movieUrl:NSURL? = NSURL(string: "http://streamapp.ir:1935/lahzenegar/\(userName)/playlist.m3u8")
#IBOutlet var inpt: UITextField!
#IBOutlet var scView: UIScrollView!
let avPlayerViewController = AVPlayerViewController()
var avPlayer: AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
}
and my button code:
#IBAction func playButtonTapped3(sender: UIButton) {
userName = "\(self.inpt.text)"
self.presentViewController(self.avPlayerViewController, animated: true) { () -> Void in
self.avPlayerViewController.player?.play()
}
print(movieUrl)
}
so i want when press button (username) change value to whatever users entered in textBox
already output:
thanks for help

When you first create the movieURL the userName is not set. That is fine, however, when you press the button you need to update the movieURL as well as the username. Something like this:
userName = "\(self.inpt.text)"
movieURL = NSURL(string: "http://streamapp.ir:1935/lahzenegar/\(userName)/playlist.m3u8")

Related

Trying to make a button change the web view url but when I press it it crashes the app

So I am trying to make an app in Xcode 8 basically I have a webview and a side bar with buttons I want to make those buttons change the webview but for some reason when I press them the app crashes.
This is the code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var menuView: UIView!
#IBOutlet weak var leadingConstraint: NSLayoutConstraint!
var menuShowing = false
#IBOutlet weak var Webview: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
menuView.layer.shadowOpacity = 1
menuView.layer.shadowRadius = 6
let url = URL(string: "http://www.peulibrary.com/application/")
Webview.loadRequest(URLRequest(url: url!))
}
#IBAction func loadSecond(_ sender: Any) {
let url = URL(string: "http://www.peulibrary.com/application/category/פעולות-גן-ג/")
Webview.loadRequest(URLRequest(url: url!))
}
when I run the app in the simulator I get an error at the second
Webview.loadRequest(URLRequest(url: url!))
that says "Thread 1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0)"
any help appreciated, thanks in advance! :)
Your URL contains special characters so encode your URL string then use it with webView.
let stringURL = "http://www.peulibrary.com/application/category/פעולות-גן-ג/"
if let encodeURL = stringURL.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: encodeURL) {
Webview.loadRequest(URLRequest(url: url))
}

iOS Swift - Properties not updating after preparing for segue

I am trying to pass a news ID of type string to the second VC and load the object based on it from Realm. When I debugged, I found that the prepare for segue is correctly setting the detailNewsVC.newsID to the primary key of my news item but the second VC is not receiving it. Any help on this?
Checks I have made:
Made sure that the detail VC identifier is correct
detailNewsVC.newsID in VC 1 is correctly setting the news ID .. This is to make sure that realm is correctly sending the newsID and it is working fine.
Changed the viewDidLoad in VC 2 to viewWillLoad..Just to make sure that second vc is not loaded before for any reason but no luck on that.
Restarted xcode
Replaced newsID in VC 2 with an actual news primary key and it's correctly pulling the related news. I think the culprit is that the VC2 property: newsID is not updating when prepare for segue is called.
First VC code for prep for segue:
extension HomeVC: UICollectionViewDelegate {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == SegueIdentifier.gotodetail.rawValue, let sendNewsID = sender as? String {
let navVC = segue.destination as? UINavigationController
let detailNewsVC = navVC?.viewControllers.first as! DetailNewsVC
detailNewsVC.newsID = sendNewsID
print("Detail News ID = \(detailNewsVC.newsID)")
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let newsID = newsArray[indexPath.row].newsId
performSegue(withIdentifier: SegueIdentifier.gotodetail.rawValue, sender: newsID)
}
}
Second VC Code:
class DetailNewsVC: UIViewController {
#IBOutlet private weak var scrollView: UIScrollView!
#IBOutlet private weak var newsTitle: UILabel!
#IBOutlet private weak var newsImage: UIImageView!
#IBOutlet private weak var newsDescription: UILabel!
var newsID = ""
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
print("News ID: \(newsID)")
guard let news = realm.object(ofType: News.self, forPrimaryKey: newsID as AnyObject) else {
print("Cannot load news")
return
}
print(news)
newsTitle.text = news.newsTitle
if let url = URL(string: news.urlToImage), let data = try? Data.init(contentsOf: url) {
newsImage.image = UIImage(data: data)
}
newsDescription.text = news.newsDescription
}
}
Move your prepare function out of the extension and put it in HomeVC. According to Apple's Swift Guide extensions cannot override existing functionality.
Extensions can add new functionality to a type, but they cannot override existing functionality.
Apple Developer Guide
It's hard to tell in which order UIKit calls the UIViewController methods, but it might be possible that viewDidLoad is getting called before you get the chance to set the value of newsID.
The following might be overkill, but it'll guarantee the views will be updated during viewDidLoad, or otherwise if newsID is set after the fact:
class DetailNewsVC: UIViewController {
#IBOutlet private weak var scrollView: UIScrollView!
#IBOutlet private weak var newsTitle: UILabel!
#IBOutlet private weak var newsImage: UIImageView!
#IBOutlet private weak var newsDescription: UILabel!
public var newsID = "" {
didSet {
updateUIForNews()
}
}
override func viewDidLoad() {
super.viewDidLoad()
updateUIForNews()
}
private func updateUIForNews() {
guard !newsID.isEmpty else {
return
}
let realm = try! Realm()
print("News ID: \(newsID)")
guard let news = realm.object(ofType: News.self, forPrimaryKey: newsID as AnyObject) else {
print("Cannot load news")
return
}
print(news)
newsTitle.text = news.newsTitle
if let url = URL(string: news.urlToImage), let data = try? Data.init(contentsOf: url) {
newsImage.image = UIImage(data: data)
}
newsDescription.text = news.newsDescription
}
}

Initializing AVAudioPlayer to be used in more than one function

Usual AVAudioPlayer tutorials online creates a AVAudioPlayer within a function to where the play and stop functions of the AVAudioPlayer object aren't available to the object directly from other functions. The problem is that I would like another function to stop the sound from the AVAudioPlayer. This seems pretty simple by initializing the objects at the top of the class in hopes it would be accessible however in Swift3 the init function for AVAudioPlayer includes a throw and a parameter for the sound file. Swift doesn't allow us to use an instance member within a property initializer so I'm stuck on my thought process of how this could be written.
The only error I'm running into at this point is not being allowed to use an instance member in the property initializer when creating "backgroundMusicPlayer":
import UIKit
import AVFoundation
class MadLibOneViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var thePlace: UITextField!
#IBOutlet weak var theVerb: UITextField!
#IBOutlet weak var theNumber: UITextField!
#IBOutlet weak var theTemplate: UITextView!
#IBOutlet weak var theStory: UITextView!
#IBOutlet weak var generateStoryButton: UIButton!
#IBOutlet weak var proceedToNextMadLib: UIButton!
//var backgroundMusicPlayer = AVAudioPlayer()
var error:NSError?
var path = Bundle.main.path(forResource: "bensound-cute", ofType: "mp3")
var url: NSURL {
return NSURL(fileURLWithPath: path!)
}
var backgroundMusicPlayer: AVAudioPlayer = try AVAudioPlayer(contentsOf: url as URL, error: &error)
#IBAction func createStory(_ sender: AnyObject) {
theStory.text=theTemplate.text
theStory.text=theStory.text.replacingOccurrences(of: "<place>", with: thePlace.text!)
theStory.text=theStory.text.replacingOccurrences(of: "<verb>", with: theVerb.text!)
theStory.text=theStory.text.replacingOccurrences(of: "<number>", with: theNumber.text!)
generateStoryButton.isHidden=true
proceedToNextMadLib.isHidden=false
}
#IBAction func showNextStory(_ sender: AnyObject) {
view.backgroundColor=UIColor.green
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let resultViewController = storyBoard.instantiateViewController(withIdentifier: "MadLibTwoViewController") as! MadLibTwoViewController
self.present(resultViewController, animated:true, completion:nil)
}
#IBAction func hideKeyboard(_ sender: AnyObject) {
thePlace.resignFirstResponder()
theVerb.resignFirstResponder()
theNumber.resignFirstResponder()
theTemplate.resignFirstResponder()
}
override func viewDidLoad() {
super.viewDidLoad()
proceedToNextMadLib.isHidden=true
view.backgroundColor = UIColor.purple
// Do any additional setup after loading the view.
self.theVerb.delegate = self
self.thePlace.delegate = self
self.theNumber.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You need to use Lazy initialisation/instantiation for that. In your case this is all you need to do.
lazy var player: AVAudioPlayer = {
[unowned self] in
do {
return try AVAudioPlayer.init(contentsOf: self.url)
}
catch {
return AVAudioPlayer.init()
}
}()
For more about Lazy Initialisation this is a good read. The interesting thing in your case is that the initialiser throws. I think this forum discussion is helpful to have a slight idea.

Make UIButton Click Display UIWebview

I'm trying to load a specific URL after clicking a button. I have the webView code inside of a UIButton action, but I'm not sure how to pull that into the display/viewDidLoad method it will work. But I need to be able to change the URL with different buttons.
import UIKit
class ViewController: UIViewController {
var radioURL = "http://www.ladiescanwetalk.org/category/podcasts/"
#IBOutlet weak var mainWebView: UIWebView!
#IBAction func loadRadioView(sender: UIButton) {
let getCurrentURL = NSURL (string: radioURL)
let requestCurrentURL = NSURLRequest(URL: getCurrentURL!)
self.mainWebView?.loadRequest(requestCurrentURL)
}
override func viewDidLoad() {
super.viewDidLoad()
}
In my opinion the best to achieve what you're asking is to set a different tag value for each value (you can do this either using Storyboard or directly via code).
Your code will be something like this:
#IBAction func loadRadioView(sender: UIButton) {
if sender.tag == 1 {
radioURL = "http://anotherUrl"
} else if sender.tag == 2 {
radioURL = "http://yetanotherurl"
} else if sender.tag == 3 {
radioURL = "http://....."
}
let getCurrentURL = NSURL (string: radioURL)
let requestCurrentURL = NSURLRequest(URL: getCurrentURL!)
self.mainWebView?.loadRequest(requestCurrentURL)
}

Setting which Text view to use to open Url

Hello am making an app where the user presses an butten and a random link opens! But i have problems with making the textview were the user presses to recognize that it is a Url to open
import UIKit
import StoreKit
class ViewController: UIViewController, UITextViewDelegate,
NSObjectProtocol {
#IBOutlet weak var randomButton: UIButton!
#IBOutlet weak var firsttext: UITextView!
let links =
["http://www.google.com","http://www.yahoo.com",
"http://www.discovery.com"]
var currentLinkIndex : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
firsttext.delegate = self
}
func textview(textview: UITextView!, shouldInteractWithURL URL: NSURL,
inRange characterRange: NSRange) -> Bool {
let url = NSURL(string:links[currentLinkIndex])
UIApplication.sharedApplication().openURL(url!)
return false
}
#IBAction func randomButtonaction(sender: UIButton) {
let random : Int = Int(arc4random()) % 3
firsttext.text = links[random]
currentLinkIndex = random
}
}
Do i have to inside "func textview...ShouldinteractWithUrl..." name that i want the firsttext to be the one thats should be enable to interact with url and then open? How do i set it to do so?

Resources