Having trouble with "removingPercentEncoding" in Swift and Cocoa

I am having difficulty getting "removingPercentEncoding" working for an NSString in Cocoa and for String in Swift


For instance I have a text file of strings (one per line) similar to sample below.


"http://www.ebay.com/itm/like/272309198212?lpid=82&chn=ps&ul_ref=http%3A%2F%2Frover.ebay.com%2Frover%2F1%2F711-117182-37290-0%2F2%3Fmtid%3D1588%26kwid%3D1%26crlp%3D110544474129_324272%26itemid%3D272309198212%26targetid..."


My Swift code

let theFile = NSHomeDirectory() + "/urls.txt"
let aString =  try String(contentsOfFile:theFile, encoding: String.Encoding.utf8)
let myStrings = aString.components(separatedBy: .newlines)
for theURL in myStrings {
    print( (theURL.removingPercentEncoding)!)
}


My Cocoa code

NSUInteger i;
NSString *theFile = [NSString stringWithUTF8String:argv[1]];
NSCharacterSet *newlineCharSet = [NSCharacterSet newlineCharacterSet];
NSString* fileContents = [NSString stringWithContentsOfFile:theFile encoding:NSUTF8StringEncoding error:nil];
NSArray *lines = [fileContents componentsSeparatedByCharactersInSet:newlineCharSet];
for( i=0; i<[lines count]; i++ ) {
     NSString *str = [lines objectAtIndex:i];
     NSLog(@"%@\n", [str stringByRemovingPercentEncoding]);
}


Both of these example iterate through the lines of the file just fine but will not remove the % encodings. I've tried all the different string encodings with the same negative results:


Now when a do a string assignment like below, it will give the expected results, but not when iterating through a file


NSString *theString = @"http://www.ebay.com/itm/like/272309198212?lpid=82&chn=ps&ul_ref=http%3A%2F%2Frover.ebay.com%2Frover%2F1%2F711-117182-37290-0%2F2%3Fmtid%3D1588%26kwid%3D1%26crlp%3D110544474129_324272%26itemid..."
NSLog(@"%@", [theString stringbyRemovingPercentEncoding]);


I've got the nagging feeling, I'm missing something very simple. Or am I not crazy and this is some kind of bug.

Accepted Reply

Inspecting my urls.txt file closer I found that the problem is that the percent (%) is itself sometimes being escaped, for example %253F and even a few where it is encoded as %25253F (really weird). The solution was to apply remmovingPercentEncoding 3 times to the string to unwrap the encoded stuff. What is the purpose in such an encoding?


So here is what is working. I suppose you could also do a replaceOccurencesofString: withString a couple times to acheive the same effect.


NSUInteger i;
NSString *theFile = [NSString stringWithUTF8String:argv[1]];
NSCharacterSet *newlineCharSet = [NSCharacterSet newlineCharacterSet];
NSString* fileContents = [NSString stringWithContentsOfFile:theFile encoding:NSUTF8StringEncoding error:nil];
NSArray *lines = [fileContents componentsSeparatedByCharactersInSet:newlineCharSet];
  
for( i=0; i<[lines count]; i++ ) {
    NSString *str = [[lines objectAtIndex:i] stringByRemovingPercentEncoding];
    str = [str stringByRemovingPercentEncoding];
    NSLog(@"%@\n", [str stringByRemovingPercentEncoding]);
}


Does anyone else have a more elegant solution?

Replies

I am having difficulty getting "removingPercentEncoding" working for an NSString in Cocoa and for String in Swift

I tried your Swift code and it works fro me. To wit:

$ cat urls.txt
http://www.ebay.com/itm/like/272309198212?lpid=82&chn=ps&ul_ref=http%3A%2F%2Frover.ebay.com%2Frover%2F1%2F711-117182-37290-0%2F2%3Fmtid%3D1588%26kwid%3D1%26crlp%3D110544474129_324272%26itemid%3D272309198212%26targetid
$ cat test.swift
import Foundation

let theFile = NSHomeDirectory() + "/urls.txt" 
let aString =  try String(contentsOfFile:theFile, encoding: String.Encoding.utf8) 
let myStrings = aString.components(separatedBy: .newlines) 
for theURL in myStrings { 
    print( (theURL.removingPercentEncoding)!) 
}
$ swift test.swift
http://www.ebay.com/itm/like/272309198212?lpid=82&chn=ps&ul_ref=http://rover.ebay.com/rover/1/711-117182-37290-0/2?mtid=1588&kwid=1&crlp=110544474129_324272&itemid=272309198212&targetid

I’m not sure why it’s not working for you but I suspect there’s something wrong with your test methodology.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Inspecting my urls.txt file closer I found that the problem is that the percent (%) is itself sometimes being escaped, for example %253F and even a few where it is encoded as %25253F (really weird). The solution was to apply remmovingPercentEncoding 3 times to the string to unwrap the encoded stuff. What is the purpose in such an encoding?


So here is what is working. I suppose you could also do a replaceOccurencesofString: withString a couple times to acheive the same effect.


NSUInteger i;
NSString *theFile = [NSString stringWithUTF8String:argv[1]];
NSCharacterSet *newlineCharSet = [NSCharacterSet newlineCharacterSet];
NSString* fileContents = [NSString stringWithContentsOfFile:theFile encoding:NSUTF8StringEncoding error:nil];
NSArray *lines = [fileContents componentsSeparatedByCharactersInSet:newlineCharSet];
  
for( i=0; i<[lines count]; i++ ) {
    NSString *str = [[lines objectAtIndex:i] stringByRemovingPercentEncoding];
    str = [str stringByRemovingPercentEncoding];
    NSLog(@"%@\n", [str stringByRemovingPercentEncoding]);
}


Does anyone else have a more elegant solution?

What is the purpose in such an encoding?

Surely that’s a question you should be asking of the whoever created the

urls.txt
file.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"