Dailymotion Player is not Working in UIWebview Swift 3 - ios

I've written the following code in Xcode 9. The ID variable comes from another viewcontroller of mine, via a segue.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ID" {
if let indexPath = self.tblview.indexPathForSelectedRow {
let controller = segue.destination as! DViewController
let value = arrRes[indexPath.row]
controller.videoId = value["id"] as! String
}
}
class DViewController : UIViewController {
#IBOutlet weak var Views: UIWebView!
var ID : String!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.dailymotion.com/embed/video/\(ID)?sharing-enable=0&ui-logo=0&endscreen-enable=0&autoplay=1")
Views.loadRequest(URLRequest(url: url!))
Views.allowsInlineMediaPlayback = true
}
}
}
When I run the code, I get the following error:
Page not found. The page you're looking for is ... restricted ...

You're getting that error because the page isn't found. Try going to that page in a browser. The link you put in your code returns a 404 page, in other words, it does not go anywhere meaningful. Your code looks fine; it's the link that is broken.
Before you start trying to debug your code, try to think of the simplest possible explanation of why it might not be working. Usually the simplest explanation is the correct explanation. In this case, the error message said it all - the page couldn't be found. There's nothing there.

Related

Passing error with "perform segue" returns nil?

I am trying to show app users the error when they login in or register in a wrong way, for example the password needs 6 characters so if he/she entered 4 or 5 its should bring him error but it only prints in Xcode and always nil in the app (I am new here and the website tells me the picture size is too big to be uploaded so ill write down). Can someone help me figure what's wrong with the code here ? Thanks!!
// This is the code for the first viewcontroller where I try to pass the error to the ErrorViewController
if let email = emailTextfield.text, let password = passwordTextfield.text{
Auth.auth().signIn(withEmail: email, password: password) { [weak self] authResult, error in
if let e = error {
print(e)
self!.performSegue(withIdentifier: "GoToError", sender: self)
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "GoToError" {
let GoTo = segue.destination as! ErrorViewController
GoTo.errorText = "\(e.localizedDescription)"}
}
}else{
self!.performSegue(withIdentifier:K.loginSegue, sender: self)
}
}
}
// This is the code of the ErrorViewController where It should catch the error and pass it to the ErrorText label and get printed to the app screen
errorText: String?
#IBOutlet weak var ViewMessage: UIView!
#IBOutlet weak var ErrorText: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
ViewMessage.layer.cornerRadius = ViewMessage.frame.size.height / 4
if errorText != nil {
ErrorText.text = errorText
}else{
// The string below is what gets printed because the error is always nil
ErrorText.text = "make sure your password is at least 6 characters"
The reason is that prepare(for segue must be implemented on the top level of the class (same level as viewDidLoad).
And please name variables, functions and enum cases with starting lowercase letter.
func prepare(for segue: UIStoryboardSegue, sender: Any?)
This function is called every time segue occurs (when performSegue(withIndentifier:sender) function calls).
viewController has no access to prepare() function because it is in local scope of if/else block.
More specifically, prepare(for segue) function exists only in scope of if/else block, that is wrapped in a closure, that is wrapped in another if/else block.
But this function should be always accessible for viewController, that why it should be placed in a top level scope.
Like that
class MyViewController: UIViewController {
//other class properties and methods
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//your code here
}
}
I would suggest to read more about scope & context in swift.

Transferring an object from a Realm database to another UITabBar controller

Tell me, please, I'm trying to solve the problem of transferring an instance of a class to another controller using the Realm database.
I have a main controller that stores objects according to the model the following data:
class Route: Object {
#objc dynamic var routeImage: Data?
#objc dynamic var routeName: String?
#objc dynamic var numberOfPersons = 0.0
#objc dynamic var dateOfDeparture: String?
#objc dynamic var dateOfArrival: String?
let placeToVisit = List<Place>()
let person = List<Person>()
}
In the controller to which I need to transfer this data, I created
var currentRoute: Route!
In the Storyboard, I specified the identifier "showDetail" from the controller cell to the UITabBar, and in the main controller, I created a method:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
guard let indexPath = tableView.indexPathForSelectedRow else {return}
let newPlaceVC = segue.destination as! InformationViewController
newPlaceVC.currentRoute = routes[indexPath.row]
}
}
Error I got:
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
Could not cast value of type 'UITabBarController' (0x111ed8b10) to 'Organizer_Tourist.InformationViewController' (0x108dd0a70).
2019-10-07 14:30:35.626853+0800 Organizer Tourist[5467:2618892] Could not cast value of type 'UITabBarController' (0x111ed8b10) to 'Organizer_Tourist.InformationViewController' (0x108dd0a70).
(lldb)
But it is not valid, the application crashes by tap on the cell. I suppose this would work if there was not a tabBar, but a regular table, view controllers. I was looking for solutions and all I came across was implementation through singleton. Now I have a lot of questions, but will this really be the right decision? People say this violates the "modularity" of the application and carries its own problems. The question is how is this done through singleton? What to consider, where to start? Which method is worth editing?
Error said what is happening:
Could not cast value of type 'UITabBarController'
You are trying to cast segue.destination to typo InformationViewController which is not.
If you embed your InformationViewController in UITabBarController so you need to cast to your UITabBarController rather than InformationViewController.
Try something like this:
if segue.identifier == "showDetail" {
guard let indexPath = tableView.indexPathForSelectedRow else { return }
let tabBarController = segue.destination as! UITabBarController
UserSelectedRoute.shared.selectedRoute = routes[indexPath.row]
}
If you want to pass current selected route to InformationViewController you can create singleton object which will be hold current route
final class UserSelectedRoute {
private init() { }
static var shared = UserSelectedRoute()
var selectedRoute: Route?
}
And then in your InformationViewController you can have something like:
var currentRoute = UserSelectedRoute.shared.selectedRoute
Hope this will help you!

why can't recordAudioURL be assigned to the segue.destination object?

I am following an online course and the instructor code has the following code, but I get an error. It might be an issue with updates on Swift or Xcode. How would you approach to fix this error?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "stopRecording" {
let playsoundsVC = segue.destination as! PlaySoundsViewController
let recordedAudioURL = sender as! URL
playsoundsVC.recordedAudioURL = recordedAudioURL
}
}
the last line of the code gives the error:
Cannot assign value of type 'URL' to type 'URL?.Type'
edit1: start of the PlaySoundsViewController file
class PlaySoundsViewController: UIViewController {
var recordedAudioURL = URL?.self
}
Make sure var inside PlaySoundsViewController is declared like this
class PlaySoundsViewController:UIViewController {
var recordedAudioURL:URL?
}
or var recordedAudioURL:URL! if it's 100% it will be assigned

Cannot take values from other view controller Swift

I want to take user settings details from this view controller and read these details to the previous view controller. I have tried many different ways, but I cannot take values until I visit this view controller
I have tried first method from this page Pass Data Tutorial
This method is also not working. I think it is very simple, but I cannot figure out the right way to do it.
class SetConvViewController: UIViewController {
var engS = "engS"
#IBOutlet weak var swithEnglish: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
if let eng2 = defaults.value(forKey: engS)
{
swithEnglish.isOn = eng2 as! Bool
}
}
let defaults = UserDefaults.standard
#IBAction func switchEng(_ sender: UISwitch) {
defaults.set(sender.isOn, forKey: engS)
}
}
If I understand you correctly from this part - „but I cannot take values until I visit this view controller” - your problem lies with the fact, that until you visit your settings, there is no value for them in UserDefaults.
If you are reading them using getObject(forKey:) method, I’d recommend you to switch to using getBool(forKey:), since it will return false even if the value has not been set yet for that key ( docs )
Anyhow, if you want to set some default/initial values you can do so in your didFinishLaunching method in AppDelegate :
if UserDefaults.standard.object(forKey: „engS”) == nil {
// the value has not been set yet, assign a default value
}
I’ve also noticed in your code that you used value(forKey:) - you should not do that on UserDefaults - this is an excellent answer as to why - What is the difference between object(forKey:) and value(forKey:) in UserDefaults?.
On a side note, if you are using a class from iOS SDK for the first time, I highly recommend looking through its docs - they are well written and will provide you with general understanding as to what is possible.
I would recommend you to store this kind of data as a static field in some object to be able to read it from any place. e.g.
class AppController{
static var userDefaults = UserDefaults.standard
}
and then you can save it in your SetConvViewController like
#IBAction func switchEng(_ sender: UISwitch) {
AppController.userDefaults.set(sender.isOn, forKey: engS)
}
and after that you can just read it from any other view controller just by calling
AppController.userDefaults
Using segues you can set to any destination whether it be next vc or previous:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "PreviousVC" {
if let prevVC = segue.destination as? PreviousViewController {
//Your previous vc should have your storage variable.
prevVC.value = self.value
}
}
If you're presenting the view controller:
Destination vc:
//If using storyboard...
let destVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DestinationViewController") as! DestinationViewController
destVC.value = self.value
self.present(destVC, animated: true, completion: nil)
Previous vc:
weak var prevVC = self.presentingViewController as? PreviousViewController
if let prevVC = prevVC {
prevVC.value = self.value
}

segue with Dictionary SWIFT

Another question which just should be simple but I am again stumped
I have created a dictionary from a log in.
It is full of values. I now want to segue to a new View controller and take the data with me
So I set up
typealias JSONDict = [String:AnyObject]
func prepareForSegue(segue: UIStoryboardSegue, sender: JSONDict!) {
if (segue.identifier == "toHome"){
var svc = segue.destinationViewController as! OtherViewController
svc.toPass2 = parsed!
Parsed shows as JSONDict - all seems well
Over on OtherViewcontroller I set up to catch it:
var toPass2:JSONDict = JSONDict()
this builds for me quite happily and segues as expected.
But when I
println("check data: \(toPass2)")
I get [:]
Nothing.
It seems to me I have built it - but nothing is coming. I could pass individual values - but all I rally want to do is bring the dictionary with me
I also tried the same thing with the unparsed data string - and this too got me a zero result.
Any help appreciated
in your OtherViewController try this:
class OtherViewController: UIViewController {
var toPass2: JSONDict? {
didSet {
println(toPass2)
}
}
}

Resources