Creating CGPDFDocument from a URL yields errors in Swift 3? - ios

The below block of code yields these two errors when I try to build. Can anybody help me out? Xcode 8 had its way with my project using its migrator and I haven't seen this error before.
let url = URL(string: "http://www.google.com")!;
var pdf:CGPDFDocument = CGPDFDocument(url);
error: cannot invoke initializer for type 'CGPDFDocument' with an argument list of type '(URL)'
note: overloads for 'CGPDFDocument' exist with these partially matching parameter lists: (CGDataProvider), (CFURL)

Hello it should like this below.
let url = URL(string: "http://www.google.com")!
fileprivate var pdfDoc: CGPDFDocument
pdfDoc = CGPDFDocument(url as CFURL)!

Related

Cannot convert value of type String to specified type NSManagedObjectContext, While converting from Swift 2.3 -> 3.2

I need Help. While conversion from Swift 2.3 -> 3.2 I received below error. I'm not able to resolve this error.
Below is my coding stuff, where I'm facing some issues.
Error1 : Cannot convert value of type String to specified type
NSManagedObjectContext**
Error2 : Cannot convert return expression of type URL to return type URL.
class func persistentFileURL(_ name: String, enclosingDirectoryName: String) -> Foundation.URL {
let directoryURL = self.directoryForPersistentStorage(enclosingDirectoryName)
let urlPath = directoryURL.path
let filePath: NSManagedObjectContext = (urlPath as NSString).appendingPathComponent(name) //Error1 : Cannot convert value of type String to specified type NSManagedObjectContext
return URL(context: filePath) // Error2 : Cannot convert return expression of type URL to return type URL.
}
Note : URL is separate Class declared to handle this : URL_Class
Please help me. I'm very new to iOS. Not able to understand this type of error.
let filePath: NSManagedObjectContext = (urlPath as NSString).appendingPathComponent(name)
should read
let filePath: String = (urlPath as NSString).appendingPathComponent(name)
Error 2:
URL doesn't have any constructor using context:. Try to use init(fileURLWithPath:) instead (which expects a string, so you need to make filePath an instance of string instead of an NSManagedObject).
See official docs on URL from Apple here.
EDIT
Seeing as you are returning a custom URL object (subclass of NSManagedObject), you need to change the return type of your function.
From -> Foundation.URL to -> URL. I'd suggest to rename your custom URL subclass to something else, since this name is already used by Apple and will probably cause some namespace issues (compiler will get confused and you will get errors).

Cannot invoke initializer for type 'URL' with no arguments - Swift 3

Receive error:
Cannot invoke initializer for type 'URL' with no arguments
Following is the code -
var databasePath = URL()
I have declare this variable globally. Also tried for
var databasePath: URL!
if let url = NSURL().absoluteURL { //error 1- Consecutive declarations on a line must be separated by ';'
databasePath = url //error2 - Variable used within its own initial value
}
Receive above 2 errors if write above code as replacement of var databasePath = URL() .
I am beginner in Swift. Please let me know the solution.
The URL initializer must have an argument.
Basically there are two types:
An URL in the file system
let databaseURL = URL(fileURLWithPath:"/path/to/file.ext")
An URL with an explicit scheme (e.g. http, ftp etc)
let databaseURL = URL(string:"http://myserver/path/to/file.ext")!
If the URL is guaranteed to be valid it can be unwrapped (!) otherwise use optical bindings (if let)
Swift- 5 Easy way
var fileDownloadedURL = URL(string: "")
Declare url in this way
var url: URL = NSURL() as URL

urlNode.objectForKeyedSubscript("href") as? String - Swift 2.3 / Swift 3 error

My code crawls up an HTML page, searches for tags, reads a table on the website and populates a tableView. This worked like a charm in Swift 2.2 but since I've updated Cocoapods, I'm having this error that is refusing to go.
Here is my function:
if let secondColumn = rowElement.childAtIndex(1) as? HTMLElement {
title = secondColumn.textContent
.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
.stringByReplacingOccurrencesOfString("\n", withString: "")
if let urlNode = secondColumn.firstNodeMatchingSelector("a") {
if let urlString = urlNode.objectForKeyedSubscript("href") as? String {
url = NSURL(string: urlString)
if url == nil {
url = NSURL.init(string: "www.mywebsitelink.com")
}
}
}
}
The error is in: urlNode.objectForKeyedSubscript("href") as? String
Error:
Downcast from 'String?' to 'String' only unwraps optionals; did you
mean to use '!'?
This worked fine before and I haven't changed any code at all in this file.
Dependencies:
Alamofire
HTMLReader
Steps taken so far:
Updated code to Swift 2.3 and Swift 3 - doesn't work.
Cleaned code, deleted derived data, etc. - doesn't work.
Tried to flip versions of the dependencies to older versions - doesn't work.
Tried to change optional values i.e. added / removed '!' or '?', tried to change the function by removing 'if let' and just declaring it.
Images of Changes:
Error: conditional binding must have optional type, not string.
Error: unavailable for scripting
Please help.
Resolved it using this syntax:
if let urlString = urlNode["href"] {
}
Not sure if it is correct but getting rid of the text after the '.' seems to be working so far.
It looks to me like your original construct,
urlNode.objectForKeyedSubscript("href")
is of type String? (optional string) not some other type. Thus the as? cast is wrong. You should just use
if let urlString = urlNode.objectForKeyedSubscript("href")? {}

Cyrillic symbols in URL

App crashes with following url:
let jsonUrl = "http://api.com/алматы/events"
let session = NSURLSession.sharedSession()
let shotsUrl = NSURL(string: jsonUrl)
let task = session.dataTaskWithURL(shotsUrl!)
Log:
fatal error: unexpectedly found nil while unwrapping an Optional value
It's because of cyrillic symbols in url. How can I solve this issue. Thanks for your help!
Swift 4
Using String Extension
Create a swift file named String+Extension.swift and paste this code
import UIKit
extension String{
var encodeUrl : String
{
return self.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
}
var decodeUrl : String
{
return self.removingPercentEncoding!
}
}
and Use it like so: (sample according to question):
"http://api.com/алматы/events".encodeUrl
Try this:
let encodedUrl = jsonUrl.stringByAddingPercentEncodingWithAllowedCharacters(URLQueryAllowedCharacterSet)
Something like this:
let apiHost = "http://api.com/"
let apiPath = "алматы/events"
let escapedPath = apiPath.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
let url = NSURL(string: "\(apiHost)\(escapedPath!)")
Obviously you should do something smarter than just force unwrap escapedPath.
Using the Wikipedia page for Swift as an example:
https://ru.wikipedia.org/wiki/Swift_(язык_программирования)
Becomes:
https://ru.wikipedia.org/wiki/Swift_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)
Which when pasted into the browser takes you to the right page (and most browsers will conveniently render the UFT-8 characters for you).
Non-ASCII characters (and many special characters) need to be escaped in a URL. Chrome and other browser do it automatically. And they unescape the URLs in the address bar for a nicer display.
So if you have a static URL, just paste it into the adressbar, press enter, selected the URL again, copy and paste it to your app:
So instead of:
let jsonUrl = "http://api.com/алматы/events"
You'll get:
let jsonUrl = "http://api.com/%D0%B0%D0%BB%D0%BC%D0%B0%D1%82%D1%8B/events"
Try stringByAddingPercentEncodingWithAllowedCharacters: defined on NSString. You may see people suggesting stringByAddingPercentEscapesUsingEncoding:, but that method is deprecated in iOS 9.
There are also a few predefined NSCharacterSets in Foundation, such as URLHostAllowedCharacterSet and URLPathAllowedCharacterSet. Therefore, if you really have to parse the unescaped URL in code (using preprocessed URLs, mentioned in the accepted answer, is usually a much better idea), you can write a helper method like this:
import Foundation
func url(scheme scheme: String, host: String, path: String) -> NSURL? {
let components = NSURLComponents()
components.scheme = scheme
components.host = host.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
components.path = path.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())
return components.URL
}
// evaluates to http://api.com/%25D0%25B0%25D0%25BB%25D0%25BC%25D0%25B0%25D1%2582%25D1%258B/events
url(scheme: "http", host: "api.com", path: "/алматы/events")
Note that the above documentation mentions that
This method is intended to percent-encode an URL component or subcomponent string, NOT an entire URL string.
That's because according RFC 3986, not all parts of an URL can be percent-encoded (e.g. scheme - http/https/etc.)
in xamarin:
var uri = new Uri (url);
var nsurl = new NSUrl (uri.GetComponents (UriComponents.HttpRequestUrl, UriFormat.UriEscaped));
UIApplication.SharedApplication.OpenUrl (nsurl);
URLs cannot contain Cyrillic characters. There are standards how to translate Cyrillic characters into valid URLs - you might find something if you search for "Punicode" (the P is intentional).

iOS8, Swift: fileURLWithPath - missing argument for parameter error

I am trying to append subdirectory to documents directory using method:
class func fileURLWithPath(path: String) -> NSURL?`
code:
let applicationDocumentsDirectory:String = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let storesDirectory:NSURL = NSURL.fileURLWithPath(applicationDocumentsDirectory).URLByAppendingPathComponent("Stores")
Getting error
missing argument for parameter 'isDirectory' in call.
I don't really get it, why compiler requires this parameter? It isn't mentioned in the interface?
Thnanx in advance
The problem is that you're trying to chain methods when there are optionals in the chain.
NSURL.fileURLWithPath(applicationDocumentsDirectory) returns NSURL? type. When you try to execute method URLByAppendingPathComponent on it, it throws a compiler error.
I know it's kind of sucks that the compiler error is totally unrelated to the real cause, but it's just a beauty of current Swift version.
Use ! to unwrap and it's gonna work properly:
let storesDirectory:NSURL =
NSURL.fileURLWithPath(applicationDocumentsDirectory)!
.URLByAppendingPathComponent(NFConstants.NFCoreDataStringIdentifiers.CoreDataStoresPathComponent.rawValue)
Of course force unwrapping the optional is potentially crashy, so even better use if let idiom:
if let baseUrl = NSURL.fileURLWithPath(applicationDocumentsDirectory) {
let storeURL = baseUrl.URLByAppendingPathComponent(NFConstants.NFCoreDataStringIdentifiers.CoreDataStoresPathComponent.rawValue)
}

Resources