Concatenating an optional and a string - ios

I have a url variable declared like this
var url:String!
url = 'hello'
then I have the base url declared like this:
var baseUrl:String
baseUrl = http://google.com/
Trying to concatenate the 2 values together like
if let tmpurl = url {
println(baseUrl + tmpurl);
}
prints out
http://google.com/Optional('hello')
Why is there the Optional part in the output? I thought the let part would unwrap the optional

The very first thing is that you are using an older version of swift. Please update to 2.1. Secondly this is because you have unwrapped the url variable but its not required. So update your code as:
For swift 2.0
var url:String?
url = 'hello'
var baseUrl:String?
baseUrl = http://google.com/
if let tmpurl = url {
print(baseUrl! + tmpurl);
}

Related

getting the output Optional("test") [duplicate]

This question already has answers here:
Unable to remove "Optional" from String
(2 answers)
Closed 2 years ago.
I tried the following code
if let shortURL = shortURL {
var url = "\(shortURL.absoluteString)"
MUser.sharedInstance.setMobileReferralId(url)
self.referralLink.text = url self.copyToClipboard()
}
For the url variable, I get the output Optional("Test"). How do I remove the "Optional" part?
The reason looks like absoluteString is optional so you can provide a default value or using if let to assign its value to url, like below
if let url = shortURL.absoluteString {
print(url)
}
or provide some default blank value like
var url = shortURL.absoluteString ?? ""
print(url)
To remove the Optional part, you only need to unwrap optional right. example:
if let shortURL = shortURL,
let url = shortURL.absoluteString {
print(url)
}

Swift: Add prefix (string) into a string

I'm looking for a String function that adds prefix string into an existing string.
The problem I've is: Sometimes, I get a URL string from web service response without keyword http:.
The general form of URL (URL string) should be: http://www.testhost.com/pathToImage/testimage.png
But sometimes I get //www.testhost.com/pathToImage/testimage.png from web service.
Now, I know that I can check, whether prefix http: is there in a string or not, but if there isn't then I need to add prefix into an existing URL string.
Is there any String (or substring or string manipulation) function that adds prefix into my URL string?
I tried into Apple document: String but couldn't find any help.
An alternate way I have is a concatenation of string.
Here is my code:
var imageURLString = "//www.testhost.com/pathToImage/testimage.png"
if !imageURLString.hasPrefix("http:") {
imageURLString = "http:\(imageURLString)" // or "http:"+ imageURLString
}
print(imageURLString)
But is there any standard way or iOS String default function that I can use here?
An alternative is URLComponents. This works with or without http
var urlComponents = URLComponents(string: "//www.testhost.com/pathToImage/testimage.png")!
if urlComponents.scheme == nil { urlComponents.scheme = "http" }
let imageURLString = urlComponents.url!.absoluteString
If "http:" + "example.com" doesn't suit you, you could write your own extension that does this:
extension String {
mutating func add(prefix: String) {
self = prefix + self
}
}
...or make it test the string before adding the prefix, to add it only if it doesn't exist yet:
extension String {
/**
Adds a given prefix to self, if the prefix itself, or another required prefix does not yet exist in self.
Omit `requiredPrefix` to check for the prefix itself.
*/
mutating func addPrefixIfNeeded(_ prefix: String, requiredPrefix: String? = nil) {
guard !self.hasPrefix(requiredPrefix ?? prefix) else { return }
self = prefix + self
}
}
Usage:
// method 1
url.add(prefix: "http:")
// method 2: adds 'http:', if 'http:' is not a prefix
url.addPrefixIfNeeded("http:")
// method 2.2: adds 'http:', if 'http' is not a prefix (note the missing colon which includes to detection of 'https:'
url.addPrefixIfNeeded("http:", requiredPrefix: "http")
There is nothing built in but you could do this in one line with a conditional assignment. See the following:
imageURLString = imageURLString.hasPrefix("http:") ? imageURLString : ("http:" + imageURLString)
I feel that this thread should be retitled to dealing more with URL String Manipulation. To return to prefixing Strings, you don't have to do this using an extension, but to use a Higher Order function (for collections)
Collections of Strings
let prefix = "Mr."
self.dataSource = myMaleFriends.map({ (friend) -> String in
return prefix + " " + friend
})
For prefixing a single word
var name = "Anderson"
name = name.withMutableCharacters({ (name) -> String in
return "Mr. " + name
})

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

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).

insert a String inside another String

How can I make this:
var originalString = "http://name.domain.com/image.jpg"
becomes this:
originalString = "http://name.domain.com/image_new.jpg"
I could not find any document about the new Range<String.Index> in Swift.
This is not a problem in Obj-C, but without any reference about Range, it suddenly becomes so confusing.
Thanks.
Edit:
Well, thanks for these solutions. However, let me give you more details about this question.
After uploading an image to server, it responds back with a String link, like above, and the image name is a random string.
The server also generates different versions of uploaded image (like Flickr). In order to get these images, I have to append a suffix into image name, it looks like this:
originalString = "http://image.domain.com/randomName_large.jpg" or "http://image.domain.com/randomName_medium.jpg"
So that's why I need to insert a String into another String. My solution is find the first . by scan the link backwardly and append a suffix before it, but the new Range<String.Index> makes it confusing.
There are some nice and useful methods on NSString that you should be able to use:
let originalString: NSString = "http://name.domain.com/image.jpg"
let extension = originalString.pathExtension // "jpg"
let withoutExt = originalString.stringByDeletingPathExtension() // "http://name.domain.com/image"
let imageName = withoutExt.lastPathComponent // "image"
let withoutFilename = withoutExt.stringByDeletingLastPathComponent() // "http://name.domain.com/"
let newString = withoutFilename
.stringByAppendingPathComponent("\(imageName)_new")
.stringByAppendingPathExtension(extension)
I only typed this into the browser (it's untested) but it should give you an idea...
This can be done with String manipulation functions. But what if the string
is
var originalString = "http://images.domain.com/image.jpg"
? You probably do not want to replace the first or all occurrences of the string
"image" here.
A better tool for this purpose might be NSURLComponents, which lets you
modify all components of a URL separately:
var originalString = "http://name.domain.com/image.jpg"
let urlComps = NSURLComponents(string: originalString)!
urlComps.path = "/image_new.jpg"
originalString = urlComps.URL!.absoluteString!
println(originalString) // http://name.domain.com/image_new.jpg
Why not using string interpolation?
var imageName = "image_new"
originalString = "http://images.domain.com/\(imageName).jpg"

Resources