In my IOS app i am using a webview to play audio from my website. My problem is that webview plays automatically when i don't even click on the webview. It says in the ios docs that mediaPlaybackRequiresUserAction is equal to true by default but it still plays. I have tried even setting mediaPlaybackRequiresUserAction to true in my code but that still doesn't solve the problem. I need to stop it from playing without user action because when the user goes to the next screen the webview automatically plays the audio. I have looked around on stack overflow and none of the solutions i found seem to help with this problem.
Here is my code:
//function to get NSURLrequest
func configureView() -> NSURLRequest {
let fileNameDownload: AnyObject = self.detailItem!
let fileNameURL = (fileNameDownload as NSString)
let spaces = fileNameURL.componentsSeparatedByString(" ")
if (spaces.count > 0) {
let fileNameURL = fileNameURL.stringByReplacingOccurrencesOfString(" ", withString: "%20", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, fileNameURL.length))
println(fileNameURL)
let url = NSURL(string: fileNameURL)
let request = NSURLRequest(URL: url!)
return request
}
else {
let url = NSURL(string: fileNameURL)
let request = NSURLRequest(URL: url!)
return request
}
}
override func viewDidLoad() {
super.viewDidLoad()
previewWebView.loadRequest(configureView())
}
Related
We are using video streaming in our Swift IOS application and it works very well. The problem is that we would like to use AVAssetResourceLoader so we can make the requests to the streaming server using our own URLSession rather than whatever AVPlayer uses (I have been completely unable to find out what session AVPlayer uses or how to influence what session it uses.)
The exact behavior is that shouldWaitForLoadingOfRequestedResource is called once for two bytes on on the .m3u8 file then it is called again asking for the whole file, and then (based on the start time) the correct .ts file is requested. After we fetch the .ts file the video player simply doesn't do anything further.
This happens whether or not we use a sample streaming video file "https://tungsten.aaplimg.com/VOD/bipbop_adv_example_v2/master.m3u8" or our own server. The sequence is identical if we don't use AVAssetResourceLoader (we can tell from our server.) right up until the .ts file is requested. At that point when we don't use the custom loader the AvPlayer brings up the video and keeps requesting .ts files. If we comment out all other interactions with the AVPlayer including setting the initial time the behavior is identical so I am only going to include the code from viewDidLoad and shouldWaitForLoadingOfRequestedResource.
Again if we simply remove the "xyzzy" prefix so that AVAssetResourceLoader isn't used, everything works. Also, I guess importantly, if we target a video file that is not a streaming file everything works either way.
One more thing our transformation of the mime type for the .ts file produced some kind of weird dynamic uti, but this doesn't seem to have anything to do with the problem because even if we hardcode the uti the same thing happens.
override func viewDidLoad() {
super.viewDidLoad()
avPlayer = AVPlayer()
avPlayerLayer = AVPlayerLayer(player: avPlayer)
videoView.layer.insertSublayer(avPlayerLayer, at: 0)
videoView.backgroundColor = UIColor.black
url = URL(string: "xyzzy" + currentPatient.videoURL())!
let asset = AVURLAsset(url: url)
asset.resourceLoader.setDelegate(self, queue: DispatchQueue.main)
let item = AVPlayerItem(asset: asset)
let avPlayerItem = item
avPlayer.replaceCurrentItem(with: avPlayerItem)
videoScrollView.delegate = self
videoScrollView.minimumZoomScale = 1.0
videoScrollView.maximumZoomScale = 6.0
}
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
let urlString = loadingRequest.request.url?.absoluteString
let urlComponents = urlString?.components(separatedBy: "xyzzy")
let url = URL(string: urlComponents![1])
let request = loadingRequest.dataRequest!
let infoRequest = loadingRequest.contentInformationRequest
let task = globalSession.dataTask(with: url!) { (data, response, error) in
self.avPlayerThread.async {
if error == nil && data != nil {
let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, response?.mimeType as! CFString, nil)
if let infoRequest = infoRequest {
infoRequest.contentType = uti?.takeRetainedValue() as? String
if request.requestsAllDataToEndOfResource == false {
infoRequest.contentLength = Int64(request.requestedLength)
} else {
infoRequest.contentLength = Int64((data?.count)!)
}
infoRequest.isByteRangeAccessSupported = true
}
if infoRequest == nil || request.requestsAllDataToEndOfResource == true {
loadingRequest.dataRequest?.respond(with: data!)
}
loadingRequest.finishLoading()
} else {
print ("error \(error)")
loadingRequest.finishLoading(with: error)
}
}
}
task.resume()
return true
}
Getting an "unexpected found nil" error, but when checking the value - its there:
override func viewDidLoad() {
super.viewDidLoad()
if whichLink == "official link" {
let urlStr = videoGame.offLink!
let url = NSURL(string: urlStr)!
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}
else if whichLink == "moby game link" {
print("yo yo yo, value is here! \(videoGame.mgLink) ")
let urlStr1 = videoGame.mgLink!
let url1 = NSURL(string: urlStr1)!
let request = NSURLRequest(URL: url1)
webView.loadRequest(request)
}
}
I'm suspecting an error in storyboard... but can't locate anything.
Did anyone has a clue what can be wrong?
The full project can be found # https://github.com/flostik2008/Favorite-Games
Your URL string is incorrectly formatted with the space at the end, so the NSURL initialization is returning nil.
You should URL encode all raw strings before trying to create an NSURL:
let urlStr1 = videoGame.mgLink!.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! should work
I have an element of a website that I want to display within a UIWebView. The element has a unique ID for css as well as for xpath. Is it possible? How would I be able to do that? Help is very appreciated.
I usualy use this code:
let url : NSURL! = NSURL(string: "http://blablablabla.com")
webView.loadRequest(NSURLRequest(URL: url))
But I don't want to display the whole page. Only the element with that ID.
I assume you are using UIWebView, not the newer WKWebView. What you need is an HTML parser (I chose HTMLReader). After downloading the page content, extract the div you want and replace the page's body with the innerHTML of that div.
The code below gets the Did you know section on Wikipedia:
import HTMLReader
override func viewDidLoad() {
super.viewDidLoad()
loadHTML()
}
func loadHTML() {
let url = NSURL(string: "https://en.wikipedia.org/wiki/Main_Page")!
let request = NSURLRequest(URL: url)
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let task = session.dataTaskWithRequest(request) { data, response, error in
guard error == nil else {
print(error!.localizedDescription)
return
}
guard let data = data else {
print("data is nil")
return
}
let html = HTMLDocument(data: data, contentTypeHeader: nil)
if let head = html.firstNodeMatchingSelector("head"),
didYouKnow = html.firstNodeMatchingSelector("#mp-dyk") {
let newHTML = "<html><head>\(head.innerHTML)</head><body>\(didYouKnow.innerHTML)</body></html>"
self.webView.loadHTMLString(newHTML, baseURL: url)
}
}
task.resume()
}
This is rather basic and is not 100% fool-proof though. See if it solves your problem.
i'm trying to open iPhone call screen with selected number when click on UIlabel which is hyperlink in swift.
a blank screen appears for 1 second and goes. No iPhone call screen appears. Don't know what is wrong in my code.
Code in viewDidLoad
let strPhone = "080 2854 2105"
let attributedPhoneStr = NSMutableAttributedString(string:strPhone, attributes:[NSLinkAttributeName: NSURL(string: "http://aerospace.honeywell.com")!])
lblPhoneContact.attributedText = attributedPhoneStr
lblPhoneContact.userInteractionEnabled = true
let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("labelPressed"))
lblPhoneContact.addGestureRecognizer(gestureRecognizer)
Function labelPressed
func labelPressed() {
let url:NSURL = NSURL(string: "tel://08028542105")!
UIApplication.sharedApplication().openURL(url)
}
what is wrong or missing in my code.
I tried running on my iPhone device.
for swift use
let url:NSURL = NSURL(string: "telprompt:08028542105")!
instead of
let url:NSURL = NSURL(string: "tel://08028542105")!
You can try to use the GCD's dispatch_async to invoke the "openURL" method:
dispatch_async(dispatch_get_main_queue()) { () -> Void in
UIApplication.sharedApplication().openURL(url)
}
You should omit the // from the uri - I.e. It should just be
let url:NSURL = NSURL(string: "tel:08028542105")!
I saw a lot of topics there and always the same problem: it's not displaying at all.
So because I am little stubborn, I want it more
This is my code :
let moviePath = NSBundle.mainBundle().pathForResource("back", ofType:"mp4");
println(moviePath!)
let movieURL = NSURL.fileURLWithPath(moviePath!)
let theMoviePlayer = MPMoviePlayerController(contentURL: movieURL!)
self.view.addSubview(theMoviePlayer.view)
theMoviePlayer.prepareToPlay()
theMoviePlayer.shouldAutoplay = true
theMoviePlayer.fullscreen = true
theMoviePlayer.play()
I checked and I have the movie file in the app's bundle resources.
The video dimension : 640 × 360 pixels
So where it can be from?
Did I forget something important ?
Edit
This new code works but always some problems :
let url = NSBundle.mainBundle().URLForResource("back", withExtension: ".mp4")
let player = MPMoviePlayerViewController(contentURL: url)
presentMoviePlayerViewControllerAnimated(player)
player.moviePlayer.prepareToPlay()
player.moviePlayer.repeatMode = MPMovieRepeatMode.One
player.moviePlayer.shouldAutoplay = true
player.moviePlayer.play()
It show me the video in landscape view and not full screen.
This is how I did it in one of my apps. You might need to call presentMoviePlayerViewControllerAnimated() and pass in the MPMoviePlayerViewController instead of doing addSubview.
let url = NSBundle.mainBundle().URLForResource("back", withExtension: ".mp4")
let player = MPMoviePlayerViewController(contentURL: url)
presentMoviePlayerViewControllerAnimated(player)
player.prepareToPlay()
player.shouldAutoplay = true
player.fullscreen = true
player.moviePlayer.play()
** Resolved **
I resolved addend the line :
player.moviePlayer.view.transform = CGAffineTransformMakeRotation(CGFloat(M_PI / 2))
Of course, it do a rotation of the video. So If it's a simple background animated like clouds or something simple, it's ok.
if there is no issue with the content type of video, call below function. It just works. :)
private func presentVideoVC(){
var url: NSURL = NSURL(string: "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v")!
var moviePlayerVC: MPMoviePlayerViewController! = MPMoviePlayerViewController(contentURL: url)
self.presentMoviePlayerViewControllerAnimated(moviePlayerVC)
}
my two cents:
in case of ios9 use https.. (or add exceptions... not good.)
dont call directly on viewDidload, it does not work, call in async to wait some time, allowing controller to be set:
dispatch_async(dispatch_get_main_queue()){
self.playIt()
}
func playIt() {
let urlString = "https://www.ingconti.com/softysit/Spinelli_short.mp4"
let url: NSURL = NSURL(string: urlString)!
let moviePlayerVC: MPMoviePlayerViewController! = MPMoviePlayerViewController(contentURL: url)
moviePlayerVC.moviePlayer.shouldAutoplay = true
self.presentMoviePlayerViewControllerAnimated(moviePlayerVC)
}
note that now MPMoviePlayerViewController is deprecated.