stringByRemovingPercentEncoding resulting in null string - objective-c

I've got a file path /Users/alexandra/Downloads/folder%20with%20spaces/ and I want to remove the percent encoding and make it a file URL. Using the method stringByRemovingPercentEncoding makes the string null.
The documentation says "A new string with the percent-encoded sequences removed, or nil if the receiver contains an invalid percent-encoding sequence.", but I don't see %20 for a space being wrong?

You didn't show us your non-working code in Objective-C, but this works fine on my machine (in Swift):
if let path = "/Users/alexandra/Downloads/folder%20with%20spaces/".removingPercentEncoding {
let url = URL(fileURLWithPath: path)
print(url) // file:///Users/alexandra/Downloads/folder%20with%20spaces/
}
On the other hand, since you've already wrongly acquired percent encoding in a string pathname, why not just stick file:// in front of it and be done with it?
let path = "/Users/alexandra/Downloads/folder%20with%20spaces/"
if let url = URL(string: "file://" + path) {
print(url)
}

Related

How is a PDF supposed to be encoded?

I'm trying to set up an API that generate PDF from web page (provided as URL). The API is gotenberg from thecodingmachine. I have it on Docker, it works just fine, I can't generate PDF through http request send with curl (for now I'm just trying to make it work, so I use the request provided as example in the documentation)
Now I am trying to make it work with my groovy/grails app. So I'm using the java tools to make the request.
Now here is my problem : the PDF file I get is blank (my app opend directly in my browser). It do has the right content, if I open it with the text editor, it's not empty, and it has almost the same content as the one I make using the curl request (which isn't blank).
I am 99% sure the problem come from the encoding. I tried changing the InputStreamReader encoding parameter, but it doesn't change anything. Here I put "X-MACROMAN" because that the encoding inside the pdf file that isn't blank, but it still doesn't change.
Here is my code :
static def execute(def apiURL)
{
def httpClient = HttpClients.createDefault()
// Request parameters and other properties.
def request = new HttpPost(apiURL)
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
builder.addTextBody("remoteURL", 'https://google.com')
builder.addTextBody("marginTop", '0')
builder.addTextBody("marginBottom", '0')
builder.addTextBody("marginLeft", '0')
builder.addTextBody("marginRight", '0')
HttpEntity multipart = builder.build()
request.setEntity(multipart)
def response = httpClient.execute(request)
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent(), "X-MACROMAN"))
StringBuffer result = new StringBuffer()
String line = ""
Boolean a = Boolean.FALSE
while ((line = rd.readLine()) != null) {
if(!a){
a = Boolean.TRUE
}
else {
result.append("\n")
}
result.append(line)
}
return result
I am 99% sure the problem come from the encoding. I tried changing the InputStreamReader encoding parameter, but it doesn't change anything. Here I put "X-MACROMAN" because that the encoding inside the pdf file that isn't blank, but it still doesn't change.
Did I made myself clear ? And does those who understands has any ideas why my PDFs are blank ?

Get the uploaded file name in play framework 2.5

I'm creating an image upload API that takes files with POST requests. Here's the code:
def upload = Action(parse.temporaryFile) { request =>
val file = request.body.file
Ok(file.getName + " is uploaded!")
}
The file.getName returns something like: requestBody4386210151720036351asTemporaryFile
The question is how I could get the original filename instead of this temporary name? I checked the headers. There is nothing in it. I guess I could ask the client to pass the filename in the header. But should the original filename be included somewhere in the request?
All the parse.temporaryFile body parser does is store the raw bytes from the body as a local temporary file on the server. This has no semantics in terms of "file upload" as its normally understood. For that, you need to either ensure that all the other info is sent as query params, or (more typically) handle a multipart/form-data request, which is the standard way browsers send files (along with other form data).
For this, you can use the parse.multipartFormData body parser like so, assuming the form was submitted with a file field with name "image":
def upload = Action(parse.multipartFormData) { request =>
request.body.file("image").map { file =>
Ok(s"File uploaded: ${file.filename}")
}.getOrElse {
BadRequest("File is missing")
}
}
Relevant documentation.
It is not sent by default. You will need to send it specifically from the browser. For example, for an input tag, the files property will contain an array of the selected files, files[0].name containing the name of the first (or only) file. (I see there are possibly other properties besides name but they may differ per browser and I haven't played with them.) Use a change event to store the filename somewhere so that your controller can retrieve it. For example I have some jquery coffeescript like
$("#imageFile").change ->
fileName=$("#imageFile").val()
$("#imageName").val(fileName)
The value property also contains a version of the file name, but including the path (which is supposed to be something like "C:\fakepath" for security reasons, unless the site is a "trusted" site afaik.)
(More info and examples abound, W3 Schools, SO: Get Filename with JQuery, SO: Resolve path name and SO: Pass filename for example.)
As an example, this will print the original filename to the console and return it in the view.
def upload = Action(parse.multipartFormData(handleFilePartAsFile)) { implicit request =>
val fileOption = request.body.file("filename").map {
case FilePart(key, filename, contentType, file) =>
print(filename)
filename
}
Ok(s"filename = ${fileOption}")
}
/**
* Type of multipart file handler to be used by body parser
*/
type FilePartHandler[A] = FileInfo => Accumulator[ByteString, FilePart[A]]
/**
* A FilePartHandler which returns a File, rather than Play's TemporaryFile class.
*/
private def handleFilePartAsFile: FilePartHandler[File] = {
case FileInfo(partName, filename, contentType) =>
val attr = PosixFilePermissions.asFileAttribute(util.EnumSet.of(OWNER_READ, OWNER_WRITE))
val path: Path = Files.createTempFile("multipartBody", "tempFile", attr)
val file = path.toFile
val fileSink: Sink[ByteString, Future[IOResult]] = FileIO.toPath(file.toPath())
val accumulator: Accumulator[ByteString, IOResult] = Accumulator(fileSink)
accumulator.map {
case IOResult(count, status) =>
FilePart(partName, filename, contentType, file)
} (play.api.libs.concurrent.Execution.defaultContext)
}

How to append link in current URL in Selenium using java

I want to know how to append link in current URL. For eg: me link is https://www.google.co.in/ in current program now I have to append /#q=ask+questions in this URL.
Please help.
I know how to get current url(by using getCurrentUrl() syntax)
Thanks
You could use URIBuilder. Something like this:
String someUrl = "https://www.google.co.in";
// or perhaps
// String someUrl = browser.getCurrentUrl();
URIBuilder uri = new URIBuilder(someUrl);
uri.setPath("search");
uri.addQueryParam("q", "ask+questions");
Assert.assertEquals(uri.toString(), "https://www.google.co.in/search?q=ask%2Bquestions");
// or perhaps
// browser.get(uri.toString());
getCurrentUrlUrl() has a return type of String. So you can save it's value and play around like you can with any String.
Take an example, I want to get this url and then append your string and then get() this new webpage:
String url = driver.getCurrentUrl();
String newurl = url+"/#q=ask+questions";
driver.get(newurl);

CFURLCopyResourcePropertyForKey failed because passed URL no scheme

I have a program that saves a file to the iCloud and this has worked great for iOS7, but now I get this error with iOS8 and cannot seem to find the answer on how to fix it. Anyone else had this problem? Any ideas would be greatly appreciated.
The Error:
CFURLCopyResourcePropertyForKey failed because it was passed this URL which has no scheme: /var/mobile/Containers/Data/Application/ASFHDDE3-B1BB-41D7-A47C-DCC328362W21/Documents/mypictostore.png
The Line of Code Throws Error:
[fileManager setUbiquitous:YES itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:#"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError];
URLS:
destinationURL: file:///private/var/mobile/Library/Mobile%20Documents/ABC23455~MY-Program/
backupUrl: /var/mobile/Containers/Data/Application/ASDFGEEW-B1BB—6FR6-A47C-DCCF21876D36/Documents/mypic.png
Thank you,
Jon
For me this problem was fixed by adding
file://
right before the file path address like this:
var filePath = "file://\(fileURLpath)"
Or maybe you can use NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mypictostore", ofType: "png")!) instead of using NSURL(string: NSBundle.mainBundle().pathForResource("mypictostore", ofType: "png")!)
Look this link for Objective-c answer: CFURLSetResourcePropertyForKey failed when disable data backup on NSDocumentDirectory
Older Swift version answer:
var str:String = "/var/mobile/Containers/Data/Application/3039975A-5E05-4A4C-8000-55C681A7C35F/Documents/index.html"
var url:URL = URL.init(fileURLWithPath: str)
Swift 4 Answer:
var str:String = "/var/mobile/Containers/Data/Application/3039975A-5E05-4A4C-8000-55C681A7C35F/Documents/index.html"
var url:URL = URL(string: str)!
Depending on what you need to do with the path, you may need to prepend the scheme file://. See more at documentation/foundation/url
If you need the file path, use fileURLWithPath:
let imageURL = URL(fileURLWithPath: imagePath)
it will give you the path as
file:///var/mobile/Containers/Data/Application/7C1D854B-8A2E-4FF0-BD30-0652AEE10B6F/Documents/image_8ZMAM.jpg
If you need the path without the scheme, use string:
let imageURL = URL(string: imagePath)
it will give you the path as
/var/mobile/Containers/Data/Application/7C1D854B-8A2E-4FF0-BD30-0652AEE10B6F/Documents/image_8ZMAM.jpg
look, I find this,The url is The location to write the data into. we should tell the system a file path.
var filePath = "file://(fileURLpath)"
var url:URL = URL.init(fileURLWithPath: fileURLpath)
Data
You can also try this, I think the following code is great as if you are not sure any particular url is correct or not for the CFURLCopyResourcePropertyForKey
if testURL.isFileURL == false {
testURL = URL(fileURLWithPath: testURL.absoluteString)
}
var url = USL(fileUrlWithString: "/private/var/...")

How to determine a file's Unicode character encoding in IOS?

In our application I have to open a text file which will be sum time UTF-8 format or UTF-16 format .
Is there any way to determine the file format of a file? Or Is it possible to check the readied 'NSString' is valid ?
You can use the following do-catch blocks as stated in the documentation if you are forced to guess the encoding of your text file, which works for Swift 4.0:
do {
let str = try String(contentsOf: url, usedEncoding: &encodingType)
print("Used for encoding: \(encodingType)")
} catch {
do {
let str = try String(contentsOf: url, encoding: .utf8)
print("Used for encoding: UTF-8")
} catch {
do {
let str = try String(contentsOf: url, encoding: .isoLatin1)
print("Used for encoding: Windows Latin 1")
} catch {
// Error handling
}
}
}
Apple's documentation has some guidance on how to proceed: String Programming Guide: Reading data with an unknown encoding:
If you are forced to guess the encoding (and note that in the absence of explicit information, it is a guess):
Try stringWithContentsOfFile:usedEncoding:error: or initWithContentsOfFile:usedEncoding:error: (or the URL-based equivalents). These methods try to determine the encoding of the resource, and if successful return by reference the encoding used.
If (1) fails, try to read the resource by specifying UTF-8 as the encoding.
If (2) fails, try an appropriate legacy encoding. "Appropriate" here depends a bit on circumstances; it might be the default C string encoding, it might be ISO or Windows Latin 1, or something else, depending on where your data is coming from.