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"
Related
I simply have string like this:
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjYwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxwYXRoIGlkPSJzdmdfMSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSIjZmZmIi8+CiAgPHJlY3Qgcng9IjYyIiBzdHJva2Utd2lkdGg9IjEwIiBpZD0ic3ZnXzIiIGhlaWdodD0iMzAzIiB3aWR0aD0iNjI5IiB5PSIxMTIiIHg9IjkxIiBzdHJva2U9IiMwMDAiIGZpbGw9IiNmZmYiLz4KICA8ZGVmcz4KICA8cmVjdCByeT0iNjMiIHJ4PSI2MyIgc3Ryb2tlLXdpZHRoPSIxMCIgaWQ9InJlY3QiIGhlaWdodD0iMTI2IiB3aWR0aD0iMTI2IiB5PSIxNTAiIHg9IjE0MCIgc3Ryb2tlPSIjMDAwIiBmaWxsPSIjZmZmIi8+CiAgPGNsaXBQYXRoIGlkPSJjbGlwIj4KICAgICAgPHVzZSB4bGluazpocmVmPSIjcmVjdCIvPgogICAgPC9jbGlwUGF0aD4KPC9kZWZzPgoKICA8dXNlIHhsaW5rOmhyZWY9IiNyZWN0IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZT0iYmxhY2siLz4KICA8aW1hZ2UgeGxpbms6aHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFHUUFBQUJrQ0FJQUFBRC9nQUlEQUFBRENrbEVRVlI0bk95ZFhVaFRjUnlHZC9SUUpFSE1WU3BwdFJiWWwwWWZHcWxZTVNnS2pNZ1V2SWt5R3RLY2RKZkVvckpGUVlyV3hReGNRUVcxQzhHaE80WE1ncUNJRWxtME1ZTkZ3VENFR3BSRk9jaWllOEVYM3Z2M3VYM1lPRHo4THM2Qi8va2QwNUdldFMxTUpERUI3RlQ0TTdDMWxoMVlZNkFOMkZ1aExMQ1B5bnFBUFhiMU1MQ2w2OUJ2dTE5ZkF6WVBPREVQeFNKUUxBTEZJbEFzQXNVaVVDd0N4U0pRTEFKejZWY1Q2TWtYZm1BYk8xY0JHNjFZQVd5aXJSN1l2dXFMd0s3SlRRRTduZDRQN0pleE9MQ0ZSY2VCMVdRUktCYUJZaEVvRm9GaUVTZ1dnV0lSS0JhQlloR1lXNWNiUUR2dHU0RDFqZXdEZHMvWlA4Q1d1SXVBdlRsVEJ1eUE3eVN3VnFRZjJPR0NsY0F1c3lXQTFXUVJLQmFCWWhFb0ZvRmlFU2dXZ1dJUktCYUJZaEdZUXpjK0FqMmJPd2RzUjBzcHNET2JEZ0o3enhVR2RuaXpHOWdsK2FlQWRlU2paNUx5WURHd3llYTd3R3F5Q0JTTFFMRUlGSXRBc1FnVWkwQ3hDQlNMUUxFSXpPTFlKNkNUbFU1Z2ExNjlBL2IzNmc1Z2I5dlBBMXUrRzkyRkY0NC9BN1lsTUFoc3dJbm1JNXhCWjJ3MFdRU0tSYUJZQklwRm9GZ0Vpa1dnV0FTS1JhQllCRVpYNmkzUU93TG9qdlpJNndmMDMyUG90UHJjNDFGZzMzaEhnTTAyUGdIMlVud2pzTDJIMERWWDJaSFZaQkVvRm9GaUVTZ1dnV0lSS0JhQlloRW9Gb0ZpRVJqcEp2VGVaMmNFdlcvNnZtRVJzTk1KZEtiOHg0TmVZUE1HMFlhY254UGJnYTNMZEFQYjAzNEMyQzAxZTlGVkFTZm1vVmdFaWtXZ1dBU0tSYUJZQklwRm9GZ0Vpa1ZndEhxalFLZlFvaHJiL2ZwSllFYzlCNEIxUjBQQTlnODFBN3Y0NzNWZy9hZVBBcnZUampaZ1B1eERwNFkwV1FTS1JhQllCSXBGb0ZnRWlrV2dXQVNLUmFCWUJFWW02UVg2elBNVXNITU5QbURqbmlwZ3ZlMXJnYlVLU29EMVAwVjdLaS9IcW9FTlhrRDdNYk5KQzFoTkZvRmlFU2dXZ1dJUktCYUJZaEVvRm9GaUVTZ1dnZWtJTlFFZGZPa0M5b3BaQit6M0N2UjFwRzIxNkp0TnY2dzd3RlorV3cvc1A5ODRzQnM4WGNER1hEbGdOVmtFaWtXZ1dBU0tSYUJZQklwRm9GZ0Vpa1dnV0FUL0F3QUEvLy9yWFpLVzhmMG5SQUFBQUFCSlJVNUVya0pnZ2c9PSIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIHk9IjE2MCIgeD0iMTYwIiBjbGlwLXBhdGg9InVybCgjY2xpcCkiLz4KCiAgPHRleHQgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgdGV4dC1hbmNob3I9InN0YXJ0IiBmb250LWZhbWlseT0iTm90byBTYW5zIEpQIiBmb250LXNpemU9IjI0IiBpZD0ic3ZnXzQiIHk9IjM0MiIgeD0iMTc5IiBzdHJva2Utd2lkdGg9IjAiIHN0cm9rZT0iIzAwMCIgZmlsbD0iIzAwMDAwMCI+YXNnZGhqYWdhc2Rqa2FzZGg8L3RleHQ+CiAgPHRleHQgdHJhbnNmb3JtPSJtYXRyaXgoMTguMDU3LCAwLCAwLCA3LjM3MzIsIC04NDI5LjI0LCAtMTkxNS40NSkiIHhtbDpzcGFjZT0icHJlc2VydmUiIHRleHQtYW5jaG9yPSJzdGFydCIgZm9udC1mYW1pbHk9IidEYW5jaW5nIFNjcmlwdCciIGZvbnQtc2l6ZT0iMSIgaWQ9InN2Z183IiB5PSIyOTAuNTEwNjEiIHg9IjQ5Ny4wODEyNyIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2U9IiMwMDAiIGZpbGw9IiNmZmYiPmU8L3RleHQ+CiA8L2c+Cjwvc3ZnPg=="
How do I convert it into UIImage using SVGKit cocoapod library?
For now I simply use:
var image: UIImage? {
guard let imageEncodedString = imageEncodedString else {
return nil
}
return SVGKImage(data: Data(base64Encoded: imageEncodedString))?.uiImage //crash here inside init
}
The beginning of the string is not base64, that's why it's failing. You need to remove first data:image/svg+xml;base64,.
You have a Data URI.
It should be like that:
data:[<media type>][;base64],<data>
You currently have:
data:image/svg+xml;base64,theBase64Image
Now, you can either remove always data:image/svg+xml;base64, from your string:
let dataURI = "data:image/svg+xml;base64,theBase64Image"
let base64String = dataURI.replacingOccurrences(of: "data:image/svg+xml;base64,", with: "")
You can also check before hand if hasPrefix() to ensure that it has the expected dataURI. You could also use a Regex, NSScanner, etc. to do so.
But since you expect SVG in base64, hasPrefix() and replacingOccurrences(of:with:) should be enough.
I would like to use a variable inside a Firestore reference. I have a sub-collections stored on the database per shop and they all have the format 'menu Shop1' or 'menu Shop2'. I have to store it this way otherwise if I use menu alone, the collectionGroup reference points to all the menus and returns them all at once - which is not what I want.
I'm struggling to pass the name of the shop to the collectionGroup reference.
This does not work:
let shopName = String("Shop1")
let collectionRef = String("menu \(shopName!)")
let ref = db.collectionGroup((collectionRef!))
But then this works:
let ref = db.collectionGroup("menu Shop1")
I have tried all the variations I know and it still wont pass the string. Does anybody know how to fix this? I'm guessing its a small tweek!
I would just concatenate the string like so:
let shopName: String = "Shop1"
let refString: String = "menu " + shopName
let ref = db.collectionGroup(refString)
Don't forget the 'space' after "menu"
You could also simplify further like so:
let shopName: String = "Shop1"
let ref = db.collectionGroup("menu " + shopName)
The argument does not need to be hard coded...
There's no need for specifying 'String'
let shopName = String("Shop1")
Just make it
let shopName = "Shop1"
Then this is not correct if the intention is to actually create a ref to a collection
let collectionRef = String("menu \(shopName!)")
it should be
let shopsCollection = db.collection("shops")
or like this
let shopName = "shop1"
let thisShop = "menu " + shopName
let shopsCollectionGroup = db.collectionGroup(thisShop)
But... I am not sure you're using the collectionGroups correctly to start with based on the names you're using.
A collection group consists of all collections with the same ID, so for example you could have a collection group of 'shops' whereas yours is called 'menu Shop1' which would indicate a single shop. Or from the guide a collectionGroup called 'landmarks' which would include landmarks from multiple cities.
Read though the Collection Group Queries guide again to ensure it's being used correctly.
As a side note, please protect your code by handling optionals properly.
shopName!
is bad news is shopName is nil as it will crash you code. See nil-coelescing operators, guard and if statements.
I would like to query a particular child from the array of color hex codes.
Here's a snapshot of my database structure:
How do I query a particular hex code and obtain the entire array of its parent object?
You cannot query whether a specific value exists in a list. This is one of the many reasons why the Firebase documentation recommends against using arrays in the database.
But in this case (and most cases that I encounter), you may likely don't really need an array. Say that you just care about what colors your user picked. In that case, you can more efficiently store the colors as a set:
palettes
-KSmJZ....A5I
"0x474A39": true
"0xbA9A7C": true
"0xDEDEDF": true
"0x141414": true
"0x323E35": true
I did it in a different way,
made a function that does this:
let databaseRef = FIRDatabase.database().reference()
let HEX1 = hex1.text! as String
let HEX2 = hex2.text! as String
let HEX3 = hex3.text! as String
let HEX4 = hex4.text! as String
let HEX5 = hex5.text! as String
let URL = url.text! as String
// First set
let colorArray1 = [HEX2, HEX3, HEX4, HEX5, URL]
databaseRef.child("palette").child(HEX1).setValue(colorArray1)
// second set
let colorArray2 = [HEX1, HEX3, HEX4, HEX5, URL]
databaseRef.child("palette").child(HEX2).setValue(colorArray2)
// third set
let colorArray3 = [HEX1, HEX2, HEX4, HEX5, URL]
databaseRef.child("palette").child(HEX3).setValue(colorArray3)
// fourth set
let colorArray4 = [HEX1, HEX2, HEX3, HEX5, URL]
databaseRef.child("palette").child(HEX4).setValue(colorArray4)
// fifth set
let colorArray5 = [HEX1, HEX2, HEX3, HEX4, URL]
databaseRef.child("palette").child(HEX5).setValue(colorArray5)
so that when I target any of the 5 hexes, it will bring me back the whole array together with it.
I have string like so "/blah//hahaha//lalala/"
Which needs to be translated into an Array of strings so that if I printed the array it would look like this print(arrayOfStrings) // prints ["blah","hahaha","lalala"]
I am new to swift so forgive me if this question is foolish
Given
let text = "/blah//hahaha//lalala/"
you can
let chunks = String(text.characters.dropFirst().dropLast()).componentsSeparatedByString("//")
and this is what you get
["blah", "hahaha", "lalala"]
There's also the URL solution
let string = "/blah//hahaha//lalala/"
let components = NSURL(fileURLWithPath: string).pathComponents!.dropFirst()
print(components)
I am using the following method to encode a string in objective - C:
+(NSString*)urlEncoded:(NSString*)string
{ return ((NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes (NULL,(CFStringRef)string, NULL,(CFStringRef)#"! '=();#&+$%#",kCFStringEncodingUTF8 )));}
Is there any counterpart for this method in Swift 2.0 ? I have tried using many solutions present on stack, but none of them could solve my problem.
You probably want to use stringByAddingPercentEncodingWithAllowedCharacters with NSCharacterSet's URL-component specific character sets:
let title = "NSURL / NSURLComponents"
let escapedTitle = title.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
The idea behind those character sets is that they're probably more correct for the uses they describe than any finite set you have. That said, you could use the same method with a set you generate yourself:
let escapeSet = NSCharacterSet(charactersInString: "! '=();#&+$%#")
let string = "sdfT&*w5e#sto([+peW7)%y9pqf])"
let escapedString = string.stringByAddingPercentEncodingWithAllowedCharacters(escapeSet.invertedSet)
// "sdfT%26*w5e%23sto%28[%2BpeW7%29%25y9pqf]%29"