I know how to convert the common NSAttributedString (which has no image) into HTML. I set the Images as NSTextAttachment to NSAttributedString. How could I convert the whole attributed string into HTML?
UIImage *image = [UIImage imageNamed:#"Test.png"];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = image;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:htmlString];
NSAttributedString *attstringImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedString appendAttributedString:attstringImage];
NSAttributedString *titleContent = (NSAttributedString *)attributedString;
NSDictionary *documentAttributes = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [titleContent dataFromRange:NSMakeRange(0, titleContent.length) documentAttributes:documentAttributes error:NULL];
NSString *html = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
Please suggest me with quick answer
I have a html file on some server. The html file only contains text no photo's or anything else.
What I want to do is download the html file and put the text into a NSString.
Is this possible?
I found some code a few minutes ago:
NSURL *url = [NSURL URLWithString:#"http://www.example.com/file.html"];
NSString *text = [[NSString alloc] initWithContentsOfURL: url
encoding: NSUTF8StringEncoding
error: nil];
But did not work
Try this :
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url
cachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval: 20];
NSError *requestError;
NSHTTPURLResponse *response = nil;
// Send request synchronously.
NSData *responseData = [NSURLConnection sendSynchronousRequest: request
returningResponse: &response
error: &requestError];
// Get the json string reponse.
NSString *stringResponse = [[NSString alloc]initWithData: responseData
encoding:NSUTF8StringEncoding];
Hi in my application i have stored data in my local database sqlite3. Now i have to upload the data form local database sqlite3 to online server. For retrieving the data i have used the dataDictionary to get all the data form the sqlite3 database. And i have converted the data in json format now the problem is how to pass this json data into my online server.
NSMutableArray *array = [[NSMutableArray alloc] init];
[self openDB];
NSString *sql = [NSString stringWithFormat:#"SELECT * FROM reg"];
const char *query_stmt = [sql UTF8String];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, nil)==SQLITE_OK) {
while (sqlite3_step(statement)==SQLITE_ROW) {
NSMutableDictionary *_dataDictionary=[[NSMutableDictionary alloc] init];
NSString *date = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
field1Str= date;
NSString *customer = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
field2Str = customer;
NSString *code1 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
field3Str = code1;
NSString *code2 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement,3)];
field4Str = code2;
[_dataDictionary setObject:[NSString stringWithFormat:#"%#",field1Str] forKey:#"Kname"];
[_dataDictionary setObject:[NSString stringWithFormat:#"%#",field2Str] forKey:#"kphone"];
[_dataDictionary setObject:[NSString stringWithFormat:#"%#",field3Str] forKey:#"karea"];
[_dataDictionary setObject:[NSString stringWithFormat:#"%#",field4Str] forKey:#"kcity"];
[array addObject:_dataDictionary];
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:array options:kNilOptions error:nil];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL *someURLSetBefore =[NSURL URLWithString:#"my url for inserting the data into my online server"];
[request setURL:someURLSetBefore];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:jsonData];
// print json:
NSLog(#"JSON summary: %#", [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding]);
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}
}
I have used this above code to pass my sqlite3 database data to my server. I have print the jsondata in log its coming as a json format data only. Please tell me how to push this data to my online server where I'm missing in the code i have stuck here for very long time its eating my head its not working please help me out.
Thanks.
I suggest that you use some proper framework for HTTP communication. Using Apple's low-level API can be quite tricky.
This is a great framework: https://github.com/AFNetworking/AFNetworking
i want to parse html content into Dictionary
EDIT:
I need to parse just simple HTML, don't need to consider the complex situation.
WEB side: when I was in the system input information, using the HTML editor. But fix the old WEB system , need to modify the place more, so temporary use parsing HTML mode in the current version of the APP。
END:
Html just like this:
<p>hahaha</p><img src="aaaa.jpg"/>heihei<img src="bbb.jpg"/>guagua
i want the result is:
text hahaha
img aaaa.jpg
text heihei
img bbb.jpg
text guagua
my code is:
//<p>hahaha</p><img src="aaaa.jpg"/>heihei<img src="bbb.jpg"/>guagua
//for this
//NSArray = {0,1,2,3,4}
//NSDictionary{Sort-Key,V}={{0,{text,hahaha}},{1,{img,aaaa.jpg}},{2,{text,heihei}},{3, {img,bbb.jpg}},{4,{text,guagua}}}
-(NSArray*)RegularExpression:(NSString *)str dic:(NSMutableDictionary**)dic
{
if(str == nil) return nil;
NSString *pgnText = str;
NSString* tags=#"<[p|div].*?>(.*?)</[p|div].*?>";
NSString *regTags = tags;
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regTags options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:pgnText
options:0
range:NSMakeRange(0, [pgnText length])];
NSMutableArray* arrItems = [[NSMutableArray alloc] initWithCapacity:[matches count]];
if(matches.count >0){
for (NSTextCheckingResult *match in matches) {
NSString *tagValue = [pgnText substringWithRange:[match rangeAtIndex:1]];
NSArray* arr = [self RegularExpression:tagValue dic:dic];
[arrItems addObjectsFromArray:arr];
}
}
else{
NSString* regTags2 = #".*?<img.*?src.*?=.*?[\"|”](.*?)[\"|”].*?/>";
NSRegularExpression *regex2 = [NSRegularExpression regularExpressionWithPattern:regTags2 options:NSRegularExpressionCaseInsensitive|NSRegularExpressionAnchorsMatchLines error:&error];
pgnText = str;
NSArray *matches2 = [regex2 matchesInString:pgnText
options:0
range:NSMakeRange(0, [pgnText length])];
for (NSTextCheckingResult *match in matches2) {
NSString *tagValue = [pgnText substringWithRange:[match rangeAtIndex:1]];
NSLog(#"%#",tagValue);
}
}
return [arrItems autorelease];
}
Who has done similar function?
Keys in a dictionary must be unique. You cannot have more than one "img" key.
Check out this SO question: Objective-C DOM XML parser for iPhone
I know that there are some caching classes introduced in the iphone sdk recently, and there is also a TTURLRequest from three20's library that allows you to cache a request to a URL. However, because I am loading the web page in UIWebView by calling UIWebView's loadRequest, those techniques are not really applicable.
Any ideas how I can save a web page so that on next app launch, I don't have to fetch from the web again for the full page? The page itself already have some ajax mechanism that updates parts of itself automatically.
There are a bunch of articles about the way the cache of the UIWebView works and the global feeling is that even if some mechanisms seems to work OK under MacOS X, the same approaches may have curious behavior under iPhone.
HOWEVER, I'm doing it by playing with the global cache that is accessed by any NSURLConnection, UIWebView included. And in my case, it works ;).
What you need to understand is the global flow:
YOU -> loadRequest on a UIWebView
This goes into NSURLCache to ask "is there something cached for this request?":
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request
From that, here's what I do to handle the cache on the disk, on my side, to speed up the load of a UIWebView:
Subclass the NSURLCache and override the get control over the -(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request selector
Reimplement this selector in such a way that if nothing has been written on the FS for this request (no cache), then do the request on your side and store the content on FS. Otherwise, return what has been previously cached.
Create an instance of your subclass and set it to the system so that it is used by your application
Now the code :
MyCache.h
#interface MyCache : NSURLCache {
}
#end
MyCache.m
#implementation MyCache
-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"CACHE REQUEST S%#", request);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray* tokens = [request.URL.relativePath componentsSeparatedByString:#"/"];
if (tokens==nil) {
NSLog(#"ignoring cache for %#", request);
return nil;
}
NSString* pathWithoutRessourceName=#"";
for (int i=0; i<[tokens count]-1; i++) {
pathWithoutRessourceName = [pathWithoutRessourceName stringByAppendingString:[NSString stringWithFormat:#"%#%#", [tokens objectAtIndex:i], #"/"]];
}
NSString* absolutePath = [NSString stringWithFormat:#"%#%#", documentsDirectory, pathWithoutRessourceName];
NSString* absolutePathWithRessourceName = [NSString stringWithFormat:#"%#%#", documentsDirectory, request.URL.relativePath];
NSString* ressourceName = [absolutePathWithRessourceName stringByReplacingOccurrencesOfString:absolutePath withString:#""];
NSCachedURLResponse* cacheResponse = nil;
//we're only caching .png, .js, .cgz, .jgz
if (
[ressourceName rangeOfString:#".png"].location!=NSNotFound ||
[ressourceName rangeOfString:#".js"].location!=NSNotFound ||
[ressourceName rangeOfString:#".cgz"].location!=NSNotFound ||
[ressourceName rangeOfString:#".jgz"].location!=NSNotFound) {
NSString* storagePath = [NSString stringWithFormat:#"%#/myCache%#", documentsDirectory, request.URL.relativePath];
//this ressource is candidate for cache.
NSData* content;
NSError* error = nil;
//is it already cached ?
if ([[NSFileManager defaultManager] fileExistsAtPath:storagePath]) {
//NSLog(#"CACHE FOUND for %#", request.URL.relativePath);
content = [[NSData dataWithContentsOfFile:storagePath] retain];
NSURLResponse* response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:#"" expectedContentLength:[content length] textEncodingName:nil];
cacheResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:content];
} else {
//trick here : if no cache, populate it asynchronously and return nil
[NSThread detachNewThreadSelector:#selector(populateCacheFor:) toTarget:self withObject:request];
}
} else {
NSLog(#"ignoring cache for %#", request);
}
return cacheResponse;
}
-(void)populateCacheFor:(NSURLRequest*)request {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSLog(#"PATH S%#", paths);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray* tokens = [request.URL.relativePath componentsSeparatedByString:#"/"];
NSString* pathWithoutRessourceName=#"";
for (int i=0; i<[tokens count]-1; i++) {
pathWithoutRessourceName = [pathWithoutRessourceName stringByAppendingString:[NSString stringWithFormat:#"%#%#", [tokens objectAtIndex:i], #"/"]];
}
NSString* absolutePath = [NSString stringWithFormat:#"%#/myCache%#", documentsDirectory, pathWithoutRessourceName];
//NSString* absolutePathWithRessourceName = [NSString stringWithFormat:#"%#%#", documentsDirectory, request.URL.relativePath];
//NSString* ressourceName = [absolutePathWithRessourceName stringByReplacingOccurrencesOfString:absolutePath withString:#""];
NSString* storagePath = [NSString stringWithFormat:#"%#/myCache%#", documentsDirectory, request.URL.relativePath];
NSData* content;
NSError* error = nil;
NSCachedURLResponse* cacheResponse = nil;
NSLog(#"NO CACHE FOUND for %#", request.URL);
//NSLog(#"retrieving content (timeout=%f) for %# ...", [request timeoutInterval], request.URL);
content = [NSData dataWithContentsOfURL:request.URL options:1 error:&error];
//NSLog(#"content retrieved for %# / error:%#", request.URL, error);
if (error!=nil) {
NSLog(#"ERROR %# info:%#", error, error.userInfo);
NSLog(#"Cache not populated for %#", request.URL);
} else {
NSURLResponse* response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:#"" expectedContentLength:[content length] textEncodingName:nil];
cacheResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:content];
//the store is invoked automatically.
[[NSFileManager defaultManager] createDirectoryAtPath:absolutePath withIntermediateDirectories:YES attributes:nil error:&error];
BOOL ok;// = [[NSFileManager defaultManager] createDirectoryAtPath:absolutePath withIntermediateDirectories:YES attributes:nil error:&error];
ok = [content writeToFile:storagePath atomically:YES];
NSLog(#"Caching %# : %#", storagePath , ok?#"OK":#"KO");
}
[pool release];
}
#end
And the use of it in your application:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* diskCachePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory, #"myCache"];
NSError* error;
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath withIntermediateDirectories:YES attributes:nil error:&error];
MyCache* cacheMngr = [[MyCache alloc] initWithMemoryCapacity:10000 diskCapacity:100000000 diskPath:diskCachePath];
[NSURLCache setSharedURLCache:cacheMngr];
This code deserves a lot of cleanup.. but the main things should be in there. I had a lot of trouble to get this working, hope this helps.
I recently found this project under github :
http://github.com/rs/SDURLCache
The approach is quite the same as my previous answer described here How to save the content in UIWebView for faster loading on next launch? , but the code looks more polished so maybe it makes sense to give it a try.
If the page has AJAX already, why not store the JavaScript/HTML in the application bundle to start rather than downloading it on the first launch? Then load the page with the code Corey gave below and let the AJAX handle hitting the network for the updated parts of the page.
Take a look at: http://allseeing-i.com/ASIHTTPRequest/ASIWebPageRequest
You can save an HTML in the documents directory and load the page directly from the documents directory on launch.
To save the webview content:
Reading HTML content from a UIWebView
To load:
NSString* path = [[NSBundle mainBundle] pathForResource:#"about" ofType:#"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];