Hey guys, I'm receiving a SIGABRT when trying to use an instance variable for anything but an NSLOG :
//Class_X.H
#interface MeldingController : UIViewController
{
NSString *refURLAsString;
}
#property (nonatomic, retain) NSString *refURLAsString;
//Class_X.M
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
self.refURLAsString = [info objectForKey:UIImagePickerControllerReferenceURL];
NSLog(#"%#",self.refURLAsString);//Successfully outputs the ReferenceURL string
}
-(void)function_abc
{
NSLog(#"%#",self.refURLAsString);//Successfully outputs the ReferenceURL string
NSURL *URL = [NSURL URLWithString:self.refURLAsString]; //SIGABRT
//Or even trying to make another string using refUrlAsString
NSString *string = [[NSString alloc]init];
string = self.refURLAsString;//SIGABRT
}
iPhone Simulator iOS version 4.3, Xcode 4.
Any ideas anyone? cheers.
Your refURLAsString is of type NSString *, but [info objectForKey:UIImagePickerControllerReferenceURL] should return a NSURL * instance according to the docs. You want:
self.refURLAsString = [[info objectForKey:UIImagePickerControllerReferenceURL] absoluteString];
The reason why the NSLog works is because it calls the description method on each object that is to be printed via the %# sequence, and that does return a string. But refURLAsString is pointing to a NSURL instead of a NSString, and that makes [NSURL URLWithString:self.refURLAsString]; crash.
try this
string =[refURLAsString copy];
Your code is screwing up refURLAsString. I can't tell you how from the posted code. Activate NSZombieEnabled for details.
Not sure exactly whats the issue is, but try string = [NSString stringWithFormat:#"%#",self.refURLAsString]; and see if it crashes here too
NSString *string = [NSString stringWithFormat:#"%#",self.refURLAsString];
no need to alloc here
Related
I got some URL's heading to certain mp3's like:
(1) localhost://blablabla/song1.mp3
(2) localhost://blablabla/songwithmorechars.mp3
and so on.
How can I crop the URL's to:
(1) song1.mp3
(2) songwithmorechars.mp3
Need to display the current song my AVAudioPlayer is playing in a UILabel.
Thanks
SOLUTION:
Here's the deal:
titleLabel.text = [[[self.audioPlayer.url absoluteString] lastPathComponent] stringByReplacingOccurrencesOfString:#".mp3" withString:#""];
Take the substring with the last / (there's a method in ObjC for that!)
NSString *sub = [url lastPathComponent];
Here's the info for that method:
NSString lastPathComponent Apple Doc
Just use [url lastPathComponent], you don't need to convert it to a string first.
use
NSString *lastString = [yourStringName lastPathComponent];
NSURL *firstURL = [NSURL URLWithString:#"localhost://blablabla/song1.mp3"];
NSString *firstString = [firstURL absoluteString];
NSLog(#"Name:%#",[firstString lastPathComponent]);
From docs:
NSURL Class Reference
NSString Class Reference
I'm new to iOS develoment, and I'm trying to write an app that can scrape a website (HTML). Scraping google is just an example - I'm planning on scraping something a bit more complex...
My code is as follows:
#import "KppleViewController.h"
#import "TFHpple.h"
#implementation KppleViewController
#synthesize theButton;
- (IBAction)buttonPressed:(UIButton *)sender {
NSLog(#"button Pressed");
NSURL *url = [NSURL URLWithString: #"http://www.google.com"];
NSData *htmlData = [NSData dataWithContentsOfURL: url];
TFHpple *xpathParse = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *elements = [xpathParse searchWithXPathQuery:#"//h3"];
TFHppleElement *element = [elements objectAtIndex:0];
NSString *h3Tag = [element content];
NSLog(#"x",h3Tag);
}
The problem is that I get an error when I attempt to write to console (via NSLog) to see if anything worked. The error that I get is "Data argument not used by format string"
I've searched all over the internet, to no avail. If I comment out the NSLog to see if I my previous code is correct, I get an error about the variable immediately above the NSlog (h3Tag) declared but not being used.
Any help would be greatly appreciated...
I'm also open to any other methods of scraping HTML...
You're being confused by this line:
NSLog(#"x",h3Tag);
All this line does is log the string x. The second argument is completely unused. What you want is something like this:
NSLog(#"%#", h3Tag);
or perhaps a bit more descriptive:
NSLog(#"h3Tag: %#", h3Tag);
The token %# inside of the format string indicates that this is where the next argument will be printed. You may want to read up on the String Format Specifiers or on Formatting String Objects in general.
use
NSLog(#"%#", h3Tag);
or
NSLog(h3Tag);
NSLog(#"x = %#",h3Tag);
Above line prints the value of h3Tag.
For more help about NSLog refer link: [http://www.cocoadev.com/index.pl?NSLog]
I have a problem with the next code:
NSDictionary * imagen = [[NSDictionary alloc] initWithDictionary:[envio resultValue]];
NSString *imagenS = [imagen valueForKey:#"/Result"];
ClaseMaestra *b1 = [[ClaseMaestra alloc]init];
NSData *imagenDecode = [[NSData alloc] initWithData:[b1 base64DataFromString:imagenS]];
NSLog(#"Decode Image:");
NSLog(#"%#", imagenDecode);
//SAVE IMAGE
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#david.png",docDirectory];
[imagenDecode writeToFile:filePath atomically:YES];
Blockquote
[envio resultValue] --> return a NSDictionary with one image in Base 64 codification.
I want decoder and save this image but in my console I have showed this message:
2011-08-23 19:19:39.750 WSStub[38501:a0f] *************************
2011-08-23 19:19:39.752 WSStub[38501:a0f] SendImage
2011-08-23 19:19:39.752 WSStub[38501:a0f] *************************
2011-08-23 19:19:39.759 WSStub[38501:a0f] -[ClaseMaestra base64DataFromString:]: unrecognized selector sent to instance 0xd00ad0
Program received signal: “EXC_BAD_ACCESS”.
ClaseMaestra interface is:
#import <Foundation/Foundation.h>
#class NSString;
#interface ClaseMaestra : NSObject
+ (NSMutableData *)base64DataFromString: (NSString *)string;
#end
I can´t understand the "unrecognized selector" error...
This is a class method and you call iton an instance of the class. You should either change it to an instance method. instead of:
+ (NSMutableData *)base64DataFromString: (NSString *)string;
Use:
- (NSMutableData *)base64DataFromString: (NSString *)string;
Or, change the call, instead of:
NSData *imagenDecode = [[NSData alloc] initWithData:[b1 base64DataFromString:imagenS]];
Use:
NSData *imagenDecode = [[NSData alloc] initWithData:[ClaseMaestra base64DataFromString:imagenS]];
What to choose depends on your needs.
base64DataFromString: is a class method (starts with a +). So instead of
ClaseMaestra *b1 = [[ClaseMaestra alloc]init];
NSData *imagenDecode = [[NSData alloc] initWithData:[b1 base64DataFromString:imagenS]];
You should do
NSData *data = [ClaseMaestra base64DataFromString:imagenS];
You are sending a class message to an instance. The receiver should be a class.
So do:
NSData *imagenDecode = [[NSData alloc] initWithData:[ClaseMaestra base64DataFromString:imagenS]];
You'll also get this error if you use the name of a private framework, eg: MPMovieView .Everyone knows you're not supposed to use those, but what I didn't know is that I was using one!
What's odd is, if you use Xibs, they load the system one and give you the same type of error (Class methods).
But if you load it in code, it shadows the system framework one. I spent a decent hour scratching my head, ensuring everything was hooked up right... it was, just needed to change how I named my custom stuff. Posting this for anyone with similar
I have some source code to get the file name of an url
for example:
http://www.google.com/a.pdf
I hope to get a.pdf
because the way to join 2 NSStrings I can get is 'appendString' which only for adding a string at right side, so I planned to check each char one by one from the right side of string 'http://www.google.com/a.pdf', when it reach at the char '/', stop the checking, return string fdp.a , after that I change fdp.a to a.pdf
source codes are below
-(NSMutableString *) getSubStringAfterH : originalString:(NSString *)s0
{
NSInteger i,l;
l=[s0 length];
NSMutableString *h=[[NSMutableString alloc] init];
NSMutableString *ttt=[[NSMutableString alloc] init ];
for(i=l-1;i>=0;i--) //check each char one by one from the right side of string 'http://www.google.com/a.pdf', when it reach at the char '/', stop
{
ttt=[s0 substringWithRange:NSMakeRange(i, 1)];
if([ttt isEqualToString:#"/"])
{
break;
}
else
{
[h appendString:ttt];
}
}
[ttt release];
NSMutableString *h1=[[[NSMutableString alloc] initWithFormat:#""] autorelease];
for (i=[h length]-1;i>=0;i--)
{
NSMutableString *t1=[[NSMutableString alloc] init ];
t1=[h substringWithRange:NSMakeRange(i, 1)];
[h1 appendString:t1];
[t1 release];
}
[h release];
return h1;
}
h1 can reuturn the coorect string a.pdf, but if it returns to the codes where it was called, after a while system reports
'double free
*** set a breakpoint in malloc_error_break to debug'
I checked a long time and foudn that if I removed the code
ttt=[s0 substringWithRange:NSMakeRange(i, 1)];
everything will be Ok (of course getSubStringAfterH can not returns the corrent result I expected.), no error reported.
I try to fix the bug a few hours, but still no clue.
Welcome any comment
Thanks
interdev
The following line does the job if url is a NSString:
NSString *filename = [url lastPathComponent];
If url is a NSURL, then the following does the job:
NSString *filename = [[url path] lastPathComponent];
Try this:
Edit: from blow comment
NSString *url = #"http://www.google.com/a.pdf";
NSArray *parts = [url componentsSeparatedByString:#"/"];
NSString *filename = [parts lastObject];
I think if you have already had the NSURL object, there is lastPathComponent method available from the iOS 4 onwards.
NSURL *url = [NSURL URLWithString:#"http://www.google.com/a.pdf"];
NSString *filename = [url lastPathComponent];
Swift 3
Let's say that your url is http://www.google.com/a.pdf
let filename = url.lastPathComponent
\\filename = "a.pdf"
This is more error free and meant for getting the localized name in the URL.
NSString *localizedName = nil;
[url getResourceValue:&localizedName forKey:NSURLLocalizedNameKey error:NULL];
I haven't tried this yet, but it seems like you might be trying to do this the hard way. The iPhone libraries have the NSURL class, and I imagine that you could simply do:
NSString *url = [NSURL URLWithString:#"http://www.google.com/a.pdf"];
NSString *path = [url path];
Definitely look for a built in function. The libraries have far more testing and will handle the edge cases better than anything you or I will write in an hour or two (generally speaking).
Wondering if there is an easy way to do a simple HTML escape/unescape in Objective C. What I want is something like this psuedo code:
NSString *string = #"<span>Foo</span>";
[string stringByUnescapingHTML];
Which returns
<span>Foo</span>
Hopefully unescaping all other HTML entities as well and even ASCII codes like Ӓ and the like.
Is there any methods in Cocoa Touch/UIKit to do this?
Check out my NSString category for XMLEntities. There's methods to decode XML entities (including all HTML character references), encode XML entities, stripping tags and removing newlines and whitespace from a string:
- (NSString *)stringByStrippingTags;
- (NSString *)stringByDecodingXMLEntities; // Including all HTML character references
- (NSString *)stringByEncodingXMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
Another HTML NSString category from Google Toolbox for Mac
Despite the name, this works on iOS too.
http://google-toolbox-for-mac.googlecode.com/svn/trunk/Foundation/GTMNSString+HTML.h
/// Get a string where internal characters that are escaped for HTML are unescaped
//
/// For example, '&' becomes '&'
/// Handles and 2 cases as well
///
// Returns:
// Autoreleased NSString
//
- (NSString *)gtm_stringByUnescapingFromHTML;
And I had to include only three files in the project: header, implementation and GTMDefines.h.
This link contains the solution below. Cocoa CF has the CFXMLCreateStringByUnescapingEntities function but that's not available on the iPhone.
#interface MREntitiesConverter : NSObject <NSXMLParserDelegate>{
NSMutableString* resultString;
}
#property (nonatomic, retain) NSMutableString* resultString;
- (NSString*)convertEntitiesInString:(NSString*)s;
#end
#implementation MREntitiesConverter
#synthesize resultString;
- (id)init
{
if([super init]) {
resultString = [[NSMutableString alloc] init];
}
return self;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
[self.resultString appendString:s];
}
- (NSString*)convertEntitiesInString:(NSString*)s {
if (!s) {
NSLog(#"ERROR : Parameter string is nil");
}
NSString* xmlStr = [NSString stringWithFormat:#"<d>%#</d>", s];
NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSXMLParser* xmlParse = [[[NSXMLParser alloc] initWithData:data] autorelease];
[xmlParse setDelegate:self];
[xmlParse parse];
return [NSString stringWithFormat:#"%#",resultString];
}
- (void)dealloc {
[resultString release];
[super dealloc];
}
#end
This is an incredibly hacked together solution I did, but if you want to simply escape a string without worrying about parsing, do this:
-(NSString *)htmlEntityDecode:(NSString *)string
{
string = [string stringByReplacingOccurrencesOfString:#""" withString:#"\""];
string = [string stringByReplacingOccurrencesOfString:#"'" withString:#"'"];
string = [string stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
string = [string stringByReplacingOccurrencesOfString:#">" withString:#">"];
string = [string stringByReplacingOccurrencesOfString:#"&" withString:#"&"]; // Do this last so that, e.g. #"<" goes to #"<" not #"<"
return string;
}
I know it's by no means elegant, but it gets the job done. You can then decode an element by calling:
string = [self htmlEntityDecode:string];
Like I said, it's hacky but it works. IF you want to encode a string, just reverse the stringByReplacingOccurencesOfString parameters.
In iOS 7 you can use NSAttributedString's ability to import HTML to convert HTML entities to an NSString.
Eg:
#interface NSAttributedString (HTML)
+ (instancetype)attributedStringWithHTMLString:(NSString *)htmlString;
#end
#implementation NSAttributedString (HTML)
+ (instancetype)attributedStringWithHTMLString:(NSString *)htmlString
{
NSDictionary *options = #{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute :#(NSUTF8StringEncoding) };
NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
}
#end
Then in your code when you want to clean up the entities:
NSString *cleanString = [[NSAttributedString attributedStringWithHTMLString:question.title] string];
This is probably the simplest way, but I don't know how performant it is. You should probably be pretty damn sure the content your "cleaning" doesn't contain any <img> tags or stuff like that because this method will download those images during the HTML to NSAttributedString conversion. :)
Here's a solution that neutralizes all characters (by making them all HTML encoded entities for their unicode value)... Used this for my need (making sure a string that came from the user but was placed inside of a webview couldn't have any XSS attacks):
Interface:
#interface NSString (escape)
- (NSString*)stringByEncodingHTMLEntities;
#end
Implementation:
#implementation NSString (escape)
- (NSString*)stringByEncodingHTMLEntities {
// Rather then mapping each individual entity and checking if it needs to be replaced, we simply replace every character with the hex entity
NSMutableString *resultString = [NSMutableString string];
for(int pos = 0; pos<[self length]; pos++)
[resultString appendFormat:#"&#x%x;",[self characterAtIndex:pos]];
return [NSString stringWithString:resultString];
}
#end
Usage Example:
UIWebView *webView = [[UIWebView alloc] init];
NSString *userInput = #"<script>alert('This is an XSS ATTACK!');</script>";
NSString *safeInput = [userInput stringByEncodingHTMLEntities];
[webView loadHTMLString:safeInput baseURL:nil];
Your mileage will vary.
The least invasive and most lightweight way to encode and decode HTML or XML strings is to use the GTMNSStringHTMLAdditions CocoaPod.
It is simply the Google Toolbox for Mac NSString category GTMNSString+HTML, stripped of the dependency on GTMDefines.h. So all you need to add is one .h and one .m, and you're good to go.
Example:
#import "GTMNSString+HTML.h"
// Encoding a string with XML / HTML elements
NSString *stringToEncode = #"<TheBeat>Goes On</TheBeat>";
NSString *encodedString = [stringToEncode gtm_stringByEscapingForHTML];
// encodedString looks like this now:
// <TheBeat>Goes On</TheBeat>
// Decoding a string with XML / HTML encoded elements
NSString *stringToDecode = #"<TheBeat>Goes On</TheBeat>";
NSString *decodedString = [stringToDecode gtm_stringByUnescapingFromHTML];
// decodedString looks like this now:
// <TheBeat>Goes On</TheBeat>
This is an easy to use NSString category implementation:
http://code.google.com/p/qrcode-scanner-live/source/browse/trunk/iphone/Classes/NSString%2BHTML.h
http://code.google.com/p/qrcode-scanner-live/source/browse/trunk/iphone/Classes/NSString%2BHTML.m
It is far from complete but you can add some missing entities from here: http://code.google.com/p/statz/source/browse/trunk/NSString%2BHTML.m
Usage:
#import "NSString+HTML.h"
NSString *raw = [NSString stringWithFormat:#"<div></div>"];
NSString *escaped = [raw htmlEscapedString];
The MREntitiesConverter above is an HTML stripper, not encoder.
If you need an encoder, go here: Encode NSString for XML/HTML
MREntitiesConverter doesn't work for escaping malformed xml. It will fail on a simple URL:
http://www.google.com/search?client=safari&rls=en&q=fail&ie=UTF-8&oe=UTF-8
If you need to generate a literal you might consider using a tool like this:
http://www.freeformatter.com/java-dotnet-escape.html#ad-output
to accomplish the work for you.
See also this answer.
This easiest solution is to create a category as below:
Here’s the category’s header file:
#import <Foundation/Foundation.h>
#interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
#end
And here’s the implementation:
#import "NSString+URLEncoding.h"
#implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
#end
And now we can simply do this:
NSString *raw = #"hell & brimstone + earthly/delight";
NSString *url = [NSString stringWithFormat:#"http://example.com/example?param=%#",
[raw urlEncodeUsingEncoding:NSUTF8Encoding]];
NSLog(url);
The credits for this answer goes to the website below:-
http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
Why not just using ?
NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
return result;
Noob question but in my case it works...
This is an old answer that I posted some years ago. My intention was
not to provide a "good" and "respectable" solution, but a "hacky" one
that might be useful under some circunstances. Please, don't use this solution unless nothing else works.
Actually, it works perfectly fine in many situations that other
answers don't because the UIWebView is doing all the work. And you can
even inject some javascript (which can be dangerous and/or useful). The performance should be horrible, but actually is not that bad.
There is another solution that has to be mentioned. Just create a UIWebView, load the encoded string and get the text back. It escapes tags "<>", and also decodes all html entities (e.g. ">") and it might work where other's don't (e.g. using cyrillics). I don't think it's the best solution, but it can be useful if the above solutions doesn't work.
Here is a small example using ARC:
#interface YourClass() <UIWebViewDelegate>
#property UIWebView *webView;
#end
#implementation YourClass
- (void)someMethodWhereYouGetTheHtmlString:(NSString *)htmlString {
self.webView = [[UIWebView alloc] init];
NSString *htmlString = [NSString stringWithFormat:#"<html><body>%#</body></html>", self.description];
[self.webView loadHTMLString:htmlString baseURL:nil];
self.webView.delegate = self;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
self.webView = nil;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.webView = nil;
NSString *escapedString = [self.webView stringByEvaluatingJavaScriptFromString:#"document.body.textContent;"];
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
// Do Nothing
}
#end