Line breaks recognition in swift - swift

I've made an app that would call data from Database via webservice, create an XML page and parse it. After that it would post a text in WebView but for some reason it can't recognise line breaks and just post the text ignoring all "\n".
Is there something I've missed?
Thanks!
This is how I add text to my WebView:
import UIKit
class PubViewController: UIViewController {
#IBOutlet weak var myWebView1: UIWebView!
var selectedFeedTitle = String()
var selectedFeedFeedContent = String()
var selectedFeedURL = String()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let feedContent:String! = "<h3>\(selectedFeedTitle)</h3>\(selectedFeedFeedContent)"
myWebView1.loadHTMLString(feedContent, baseURL: nil)
}

Line breaks are ignored in HTML. You have to use the <br/> tag:
let feedContent:String! = "<h3>\(selectedFeedTitle)</h3>\(selectedFeedFeedContent)"
.stringByReplacingOccurrencesOfString("\n", withString: "<br/>")

Related

How can I add UIView to UITextView

I'm trying to append a UIView inside a UITextView. Visually speaking it would be some text, banner, more text.
This is what I tried:
// does nothing
text.textContainer.exclusionPaths = [UIBezierPath(rect: view.frame)]
// works but it also removes the text
text.addSubview(view)
This is my class
class ViewController: BannerController {
#IBOutlet weak var text: UITextView!
override func viewDidLoad() {
let view = UIView()
banners.append(view)
let myString = NSMutableAttributedString(string: "Text at the beginning\n")
super.viewDidLoad()
// text.textContainer.exclusionPaths = [UIBezierPath(rect: view.frame)]
// text.addSubview(view)
text.attributedText = myString
}
}
I also saw this https://github.com/vlas-voloshin/SubviewAttachingTextView, but I couldn't figure it out how to apply to my code.
Is it even possible? I'm new at Swift and I have no idea what to do.
If you want to use https://github.com/vlas-voloshin/SubviewAttachingTextView
Just follow below link:
https://github.com/vlas-voloshin/SubviewAttachingTextView/blob/master/Example.playground/Contents.swift

views are merged instead of showing them separately

I have two xib file, one which shows login view and another which shows the steps what to do after the login is successful. I am having hard time to make it work. I have created macos project not ios and using safariservices so that it will work for the safari extension either.
Here is what i have done
import SafariServices
class SafariExtensionViewController: SFSafariExtensionViewController {
#IBOutlet weak var passwordMessage: NSTextField!
#IBOutlet weak var emailMessage: NSTextField!
#IBOutlet weak var message: NSTextField!
#IBOutlet weak var email: NSTextField!
#IBOutlet weak var password: NSSecureTextField!
static let shared = SafariExtensionViewController()
override func viewDidLoad() {
self.preferredContentSize = NSSize(width: 300, height: 250)
message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
}
override func viewDidAppear() {
if let storedEmail = UserDefaults.standard.object(forKey: "email") as? String {
if let stepView = Bundle.mainBundle.loadNibNamed(NSNib.Name(rawValue: "ExtensionStepsViewController"), owner: nil, topLevelObjects: nil)[0] {
self.view.addSubview(stepView)
}
}
}
#IBAction func userLogin(_ sender: Any) {
let providedEmailAddress = email.stringValue
let providedPassword = password.stringValue
let isEmailAddressValid = isValidEmailAddress(emailAddressString: providedEmailAddress)
self.message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
if isEmailAddressValid && providedPassword.count > 0 {
/* login process is handled here and store the email in local storage /*
/* TODO for now email is not stored in browser localstorage which has to be fixed */
let controller = "ExtensionStepsViewController"
let subview = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: controller), bundle: nil)
self.view.addSubview(subview.view)
}
}
}
This way i get error like Type Bool has no subscript members my file structure looks something like this.
SafariExtensionViewController.xib (main one which is shown initially
with login screen)
SafariExtensionViewController.swift
ExtensionStepsViewController.xib(this view should be shown when user
is logged in instead of login screen)
ExtensionStepsViewController.swift
I am using xcode 10, swift 4, everything new.
UPDATE
I used the following block both in viewDidAppear(if there is email in localstorage then show extension steps view instead of login screen) and inside login function when the login is success but it does not navigate to that ExtensionStepsView
let controller = "ExtensionStepsViewController"
let subview = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: controller), bundle: nil)
self.view.addSubview(subview.view)
Use case is show login at initial but if user is logged in then show another view but issue is now the view are merged
You got the error "Type Bool has no subscript members" because loadNibNamed(_:owner:topLevelObjects:) method of Bundle returns Bool struct that has no subscript members so you can't write like
true[0]
How to use this method correctly see the link and example from there:
var topLevelObjects : NSArray?
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: "ExtensionStepsViewController"), owner: self, topLevelObjects: &topLevelObjects) {
let topLevelObjects!.first(where: { $0 is NSView }) as? NSView
}
Views were merged because you didn't remove previous views from the superview and added view from ExtensionStepsViewController to the same superview.
You can do the following steps to complete your issue:
Make SafariExtensionViewController inherited from SFSafariExtensionViewController that will be container (and parent) for two child view controllers such as LoginViewController and ExtensionStepsViewController and will be used to navigate between ones.
Make separately LoginViewController and ExtensionStepsViewController (both inherited from simple NSViewController) and its xibs.
Right after user logins transit from LoginViewController to ExtensionStepsViewController
As an example but instead of ParentViewController you have to use your implementation SafariExtensionViewController as I explain above in the first step.
public protocol LoginViewControllerDelegate: class {
func loginViewControllerDidLoginSuccessful(_ loginVC: LoginViewController)
}
public class LoginViewController: NSViewController {
weak var delegate: LoginViewControllerDelegate?
#IBAction func login(_ sender: Any) {
// login logic
let isLoginSuccessful = true
if isLoginSuccessful {
self.delegate?.loginViewControllerDidLoginSuccessful(self)
}
}
}
public class ExtensionStepsViewController: NSViewController {
}
public class ParentViewController: NSViewController, LoginViewControllerDelegate {
weak var login: LoginViewController! // using of force unwrap is anti-pattern. consider other solutions
weak var steps: ExtensionStepsViewController!
public override func viewDidLoad() {
let login = LoginViewController(nibName: NSNib.Name(rawValue: "LoginViewController"), bundle: nil)
login.delegate = self
// change login view frame if needed
login.view.frame = self.view.frame
self.view.addSubview(login.view)
// instead of setting login view frame you can add appropriate layout constraints
self.addChildViewController(login)
self.login = login
let steps = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: "ExtensionStepsViewController"), bundle: nil)
steps.view.frame = self.view.frame
self.addChildViewController(steps)
self.steps = steps
}
// MARK: - LoginViewControllerDelegate
public func loginViewControllerDidLoginSuccessful(_ loginVC: LoginViewController) {
self.transition(from: self.login, to: self.steps, options: .slideLeft) {
// completion handler logic
print("transition is done successfully")
}
}
}
Here is a swift playground with this example.
UPD:
You can instantiate NSViewController in several ways:
Use NSStoryboard that allows to load view of NSViewController from .storyboard file:
let storyboard = NSStoryboard(name: NSStoryboard.Name("NameOfStoryboard"), bundle: nil)
let viewController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("NSViewControllerIdentifierInStoryboard"))
Use appropriate initialiser of NSViewController to load view of it from .xib file:
let steps = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: "ExtensionStepsViewController"), bundle: nil)
Use default initialiser but you have to load view directly by overriding loadView() method if name of xib file is different from name of view controller class:
let steps = ExtensionStepsViewController()
// Also you have to override loadView() method of ExtensionStepsViewController.

Default website when web browser launches xcode swift

I have been creating my own web browser and have successfully done that in xcode. But then I wanted a certain url google for example to load when it first opens, now I have been having issues with this. If anyone can explain to me how to do this it would be great. I have tried multiple things in my ViewController class, but nothing seems to work.
Here's my code snippet, if there's something wrong with it could you tell me? :) thanks
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet weak var webView: WebView!
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://www.google.com/"
self.webView.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string: urlString)! as URL))
}
override var representedObject: Any? {
didSet {
}
}
}
The API changed quite a bit in Swift 3. Here is the code that works:
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet weak var webView: WebView!
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://www.google.com/"
let request = URLRequest(url: URL(string: urlString)!)
self.webView.mainFrame.load(request)
}
}
All the Foundation classes dropped the NS prefix (https://github.com/apple/swift-evolution/blob/master/proposals/0086-drop-foundation-ns.md) and because they changed the way parameters work, the load function changed quite a bit.

swift open website with a webview

My first app with swift... failing terribly.
I'm trying to open a website using webview and found this code online.
class ViewController: UIViewController {
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "http://www.sourcefreeze.com")
let request = NSURLRequest(URL: url!)
webView.loadRequest(request)
}
Well I get a fatal error: unexpectedly found nil while unwrapping an Optional value
Why should this value be null ?!
One of two things may be going on.
Your webView is not hooked up to a storyboard element.
Your URL object isn't be initialized
I think it's the former, but I've taken the liberty of making your code safer by optionally binding your NSURL object.
class ViewController: UIViewController {
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
if let url = NSURL(string: "http://www.sourcefreeze.com") {
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}
}
Change webView.loadRequest(request) to webView?.loadRequest(request).
You need to unblock Transport Security which doesn't allow http loads. Try this.

UIWebView is not displaying (Swift)

I am just trying to create a simple webview inside a view controller.
Here is my code:
import UIKit
class test:UIViewController{
#IBOutlet weak var myWebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var myString = "http://www.google.com"
let myURL = NSURL(string: myString)
let myReq = NSURLRequest(URL: myURL)
myWebView.loadRequest(myReq)
println(myWebView.loading)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I'm not getting any errors, simply a white screen. The loading check returns false. It seems like it should be the outlet connection, but I am sure I've made the proper connection. I ctrl-dragged the blue UIWebView element from storyboard into the class as the UIWebView! object and named it myWebView. The circle is filled in on the swift file indicating a connection, and they match up in the connections on the storyboard.
This code originally worked fine for me, but now it does not. I tried creating a completely new project and it still is not working. Adding the UIWebViewDelegate protocol to the class didn't work I've looked at the solutions on the following links, but they do not apply:
link1
link2
I'm out of ideas. Anyone got anything?
Thanks!
This is what you wan in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var myWeb = UIWebView(frame: CGRect(x: 40, y: 100, width: 240, height: 128))
var myString = "http://www.google.com"
let myURL = NSURL(string: myString)
let myReq = NSURLRequest(URL: myURL!)
myWeb.loadRequest(myReq)
view.addSubview(myWeb)
println(myWeb.loading)
}
Be careful, you have another web view (called myWebView) from the storyboard, as an outlet and that is not used. By writing the above code you create a new web view programmatically (called myWeb).