iOS video not playing (play button crossed out) - ios

I'm trying to play a video from URL, but when I run the code, all I can see is the play button crossed out.
here is the code:
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
#IBAction func playVideo(_ sender: Any) {
let videoURL = URL(string: "http://techslides.com/demos/sample-videos/small.mp4")
let player = AVPlayer(url: videoURL!)
let playerControler = AVPlayerViewController()
playerControler.player = player
present(playerControler, animated: true) {
player.play()
}
}
Xcode 9.1
Swift 4
Any idea what is wrong?

You need to edit your .plist file to be able to get video by given http URL
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
Add this code to your .plist xml, or simply try to load https: video:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>

Related

How to set root view controller in Today extension programmatically

I have a project without storyboard. I've set root view controller in AppDelegate. Now I've added a today extension. I got a new storyboard MainInterface.storyboard with root view controller TodayViewController. How can I delete MainInterface.storyboard and set root view controller programmatically?
Xcode 11.0
Open Info.plist from your Extension and change
<dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
...
</dict>
to:
<dict>
<key>NSExtensionPrincipalClass</key>
<string>NameOfYourExtension.NameOfYourViewController</string>
...
</dict>
Delete MainInterface.storyboard and it should work without any faults.
Using the URL Scheme to achieve your goal, See this code.
Write the following code in TodayViewController (Today extension swift file)
#IBAction func buttonTapped(_ sender: UIButton) {
let url = URL(string: "MyAppTodayExtension://")!
self.extensionContext?.open(url, completionHandler: { (success) in
if (!success) {
print("error: failed to open app from Today Extension")
}
})
}
Add URL Scheme in your info.plist file
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>MyAppTodayExtension</string>
</array>
</dict>
</array>
When you tap in today extension then get call following method in AppDelegate.swift file.
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
//Write code here for navigating to a specific controller OR set root view controller
return true
}

System.Net.WebException: An SSL error has occurred and a secure connection to the server cannot be made

Already found the same thread here, but that not resolved my problem.
I have added NSAppTransportSecurity and NSAllowsArbitraryLoads in info.plist.
Screenshot:
Added the below codes from this article.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>pm-admin.smartwcm.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowInsecureHTTPSLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
<key>NSThirdPartyExceptionAllowInsecureHTTPSLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
I am using HTTP REST APIs. When running the project I am getting the following exception:
System.Net.WebException: An SSL error has occurred and a secure connection to the server cannot be made. ---> Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?
Am I missing something or do anything wrong?
Cause: Since iOS 9, iOS will only allow your application to communicate with servers that implement best-practice security by default. Values must be set in Info.plist to enable communication with insecure servers.It seems that you only AllowInsecureHTTPSLoads but forget to add AllowsInsecureHTTPLoads
Solution: Add the following code in your info.plist to trust your domain.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>pm-admin.smartwcm.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
......
</dict>
</dict>
Here is a similar issue that you can refer.
Because you must to use certificate.
class ViewController: UIViewController, URLSessionDelegate,URLSessionTaskDelegate {
var urlSession: Foundation.URLSession!
override func viewDidLoad() {
super.viewDidLoad()
urlSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let serverTrust = challenge.protectionSpace.serverTrust
let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)
let policies = NSMutableArray();
policies.add(SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))
SecTrustSetPolicies(serverTrust!, policies);
var result: SecTrustResultType = SecTrustResultType(rawValue: 0)!
SecTrustEvaluate(serverTrust!, &result)
let isServerTrusted:Bool = (result == SecTrustResultType.unspecified || result == SecTrustResultType.proceed)
let remoteCertificateData:NSData = SecCertificateCopyData(certificate!)
let pathToCert = Bundle.main.path(forResource: "certificateName", ofType: "crt")
let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!
let credential:URLCredential = URLCredential(trust: serverTrust!)
completionHandler(.useCredential, credential)
}
}

How do I perform an insecure URLSession query in iOS

I'm trying to perform a query to a website that I run. However, currently, this website's certificate is invalid (for a valid reason for now).
I'm trying to query it with this code:
private static func performQuery(_ urlString: String) {
guard let url = URL(string: urlString) else {
return
}
print(url)
URLSession.shared.dataTask(with: url) {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
}
guard let data = data else {
return
}
do {
let productDetails = try JSONDecoder().decode([ProductDetails].self, from: data)
DispatchQueue.main.async {
print(productDetails)
}
} catch let jsonError {
print(jsonError)
}
}.resume()
}
However, I get:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mydomain.com” which could put your confidential information at risk.
How can I make an insecure URLSession query (equivalent to -k in CURL)?
I've tried setting these:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>mydomain.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
And yes I don't intend to release this to the App Store with insecure access, but I need to get the code tested and right now we can't get a valid certificate, so this is purely for development purposes.
First, set the delegate of the session to your class which conforms to URLSessionDelegate like :
let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main)
Add the implementation of didReceiveChallenge method in your class which conforms to URLSessionDelegate protocol
public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
This will allow insecure connection by trusting the server.
WARNING : DO NOT use this code in production apps, this is a potential security risk.
Try these exceptions:
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>

How to load CSS and JS files of a website using UIWebViews in Xcode 7.2?

I'm new to Swift programming and I'm trying to load the web content of a website into my app using UIWebView. But all I get is the skeleton of the webpage i.e. the html. How should I load the css and javascript of the website?
This is my ViewController.swift file.
//
// ViewController.swift
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = NSURL(string: "http://www.smartanalyzers.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!)
{
(data, response, error) in
if error == nil {
var urlContent = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(urlContent)
dispatch_async(dispatch_get_main_queue()){
self.webView.loadHTMLString(urlContent! as String, baseURL: nil) }
}
}
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You can load the website in a much simpler way:
if let url = NSURL(string: "http://www.smartanalyzers.com") {
webView.loadRequest(NSURLRequest(URL: url))
}
However when running this in iOS9 you need to disable Apple's App Transport Security for this website or it will not load, because it does not use HTTPS.
To allow HTTP loads from the website's domain you have to add this to your Info.plist file:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>smartanalyzers.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
If you see that fonts or images are still not loaded correctly, check if they are loaded from different domains and add those domains to the NSExceptionDomains Dictionary in Info.plist

UIWebView Issue in Swift [duplicate]

This question already has answers here:
How do I load an HTTP URL with App Transport Security enabled in iOS 9? [duplicate]
(8 answers)
Closed 7 years ago.
My UIWebView will not load and I am extremely confused why.The webview was working a few weeks ago. The site that it linked to got updated. But for some reason now any link I send to it doesn't work. I tried clearing the cache. I am a little lost to why this wont appear. Internet on my phone works fine. Everything in the storyboard is connected properly.
The activity indicator keeps spinning. And my alert comes up from the didFailLoadWithError, which is supposed to happen, but it would be nice to figure out why it won't connect.. Any help would be great, thank you.
class CommunityViewController: UIViewController, UIWebViewDelegate {
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
#IBOutlet weak var communityWeb: UIWebView!
var refreshControl:UIRefreshControl!
let url = "http://www.google.com"
override func viewWillAppear(animated: Bool) {
NSURLCache.sharedURLCache().removeAllCachedResponses()
NSURLCache.sharedURLCache().diskCapacity = 0
NSURLCache.sharedURLCache().memoryCapacity = 0
}
override func viewDidLoad() {
super.viewDidLoad()
self.communityWeb.delegate = self
let requestURL = NSURL(string:url)
let request = NSURLRequest(URL: requestURL!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 3.0)
communityWeb.loadRequest(request)
self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.communityWeb.scrollView.addSubview(refreshControl)
}
func refresh(sender:AnyObject)
{
let requestURL = NSURL(string:url)
let request = NSURLRequest(URL: requestURL!)
communityWeb.loadRequest(request)
refreshControl.endRefreshing()
}
func webViewDidStartLoad(webView: UIWebView) // here show your indicator
{
self.activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView) {
self.activityIndicator.stopAnimating()
self.activityIndicator.hidesWhenStopped = true
self.communityWeb.scrollView.contentSize.width = self.communityWeb.frame.size.width
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
let alertView = SIAlertView(title: "Internet Connection", andMessage: "Connect to the internet to receive latest updates from the Community")
alertView.addButtonWithTitle("OK", type: SIAlertViewButtonType.Default, handler:
{alertView in
NSLog("pressed")
})
alertView.transitionStyle = SIAlertViewTransitionStyle.Fade
alertView.show()
}
I think you forgot to update your info.plist file.
Add this key into your file:
The lazy option is:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Or you can directly add that into your info.plist and it will look like:
And you can add a specific domain like:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>

Resources