Newsstand icon not updating - ios

Ive been trying to figure this out now for over a week and for some reason, no matter what i do, the newsstand icon is not updating via code.
I have read through the Apple developer documentation and tripple checked my image dimensions and they are all correct. I even went and created a new class just for updating the newsstand icon.
Anyway, here is my code:
#import "NewsstandIcon.h"
#import <NewsstandKit/NewsstandKit.h>
#implementation NewsstandIcon
-(void)setIcon:(NSString *)withURL
{
// TEMPORARY OVERRIDE
withURL = #"http://www.imgtag.me/735x1024";
_downloadedData = [[NSMutableData alloc] init];
[_downloadedData setLength: 0];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:withURL]];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"[ICON DOWNLOAD] Starting download");
}
// DOWNLOAD METHODS
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
if ([response statusCode] == 404)
{
NSLog(#"[ICON DOWNLOAD] Failed - Error 404 - File not found");
[connection cancel];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"[ICON DOWNLOAD] Received Data");
[_downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"[ICON DOWNLOAD] Completed. Length %d", [_downloadedData length]);
[[UIApplication sharedApplication] setNewsstandIconImage: [[UIImage alloc] initWithData: _downloadedData]];
NSLog(#"[ICON DOWNLOAD] Setting Icon");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"[ICON DOWNLOAD] Failed - %#", [error description]);
}
#end
And this outputs:
2014-03-08 16:53:24.308 magazine[3590:70b] [ICON DOWNLOAD] Received Data
2014-03-08 16:53:24.308 magazine[3590:70b] [ICON DOWNLOAD] Completed. Length 12833
2014-03-08 16:53:25.892 magazine[3590:70b] [ICON DOWNLOAD] Setting Icon
I also had the downloaded image write to the local file system. I then browsed to the file and the image was fully intact and readable.
As you can see in the code, i have temporarily overwritten the withURL parameter of the setIcon method. I have tried this with many images and none of them work. You can see the file size in my output.
When i call setNewsstandIcon i get no warnings in my output and the icon just stays as the default icon.
Any help would be greatly appreciated!
Thanks.

If your icon doesn't follow the specifications it will result in a nil icon. take a look at this: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/NewsstandIcons.html#//apple_ref/doc/uid/TP40006556-CH28-SW1
note: remember to set a uiimage with scale 2 for retina

Related

connectionDidFinishLoading calls before image has downloaded?

I am trying to retrieve a Facebook profile picture, however I am having trouble being able to check when the image has been downloaded?
First I create a variable.
#property (strong, nonatomic) NSMutableData *imageData;
Than I start the connection.
-(void)getUserPicture {
//Grab user profile picture
imageData = [[NSMutableData alloc] init]; // the image will be loaded in here
NSString *urlString = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture?type=large", userId];
NSMutableURLRequest *urlRequest =
[NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest
delegate:self];
if (!urlConnection) NSLog(#"Failed to download picture");
}
After that I try to check when it is done so I can upload the file to my backend, however my problem is connectionDidFinishLoading calls almost instantly before the image has downloaded.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
imageData = [NSMutableData data];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[imageData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
userPicture = [UIImage imageWithData:imageData];
NSLog(#"%#",userPicture); //this returns null :(
}
The weird thing is if I call this method twice, the NSLog doesn't return null, it actually returns the photo. So why is connectionDidFinishedLoading calling before the image has downloaded from Facebook?
The problem is almost certainly neither NSURLConnection nor the Facebook API, but rather how you're calling it. But, your question doesn't include enough information for us to diagnose it.
So, first, expand your methods to include more diagnostic information, for example:
// check the response header when we receive the response
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
imageData = [NSMutableData data];
// if `statusCode` is not 200, show us what it was ...
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
int statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(#"Status code was %ld, but should be 200.", (long)statusCode);
NSLog(#"response = %#", response);
}
}
}
// make sure to detect and report any errors
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"didFailWithError: %#", error);
}
// when you're done, if we fail to create `UIImage`, then it obviously
// wasn't an image, so let's see what it was.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
userPicture = [UIImage imageWithData:imageData];
// if not an image, then ...
if (!userPicture) {
NSString *responseString = [[NSString alloc] initWithData:imageData encoding:NSUTF8StringEncoding];
if (responseString) {
// if it was a string, show it to us ...
NSLog(#"did not receive image: responseString = %#", responseString);
} else {
// if neither a string nor image data, then what was it ...
NSLog(#"did not receive image: imageData = %#", imageData);
}
}
// By the way, I'd expect to see you do something here to update the UI with the image;
// all of these delegate methods were called asynchronously, so you have
// to do something here that triggers the update of the UI, e.g.
//
// self.imageView.image = userPicture
}
By the way, I typed the above without the benefit of Xcode's syntax checking and the like, so don't be surprised if there are some errors there. But worry less about the actual code and focus on the the three diagnostic pillars this illustrates: 1. Look at the response headers and make sure they're ok, not reporting some non-200 status code; 2. Implement delegate that will report networking errors; and 3. If image conversion failed, then you obviously didn't receive an image, so stop and figure out what you actually received. (Often if the server had trouble fulfilling your request, the response is actually HTML or something like that which tells you why it had problems. If you don't look at it, you're flying blind.)
Second, you can watch the network connection by using Charles (or something like that). Run the app on the simulator and then watch the network connection as the app runs.
Third, if you're still having problems, create a MCVE. Namely, we don't want to see all of your code, but you should instead create the simplest possible example that manifests the problem you describe. Don't ask us to pour through tons of code, but rather make it as absolutely bare-bones as possible.
So I'm not sure why connectionDidFinishLoading is getting called instantly after you set the connection, but I may be able to help you work around the issue.
Try this:
-(UIImage *) getImageFromURL:(NSString *)fileURL {
UIImage * result;
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
result = [UIImage imageWithData:data];
return result;
}
Where fileURL is the a string with the url.
If you want to perform an action after the request is sent try this instead:
-(UIImage *) getImageFromURL:(NSString *)fileURL {
UIImage * result;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
result = [UIImage imageWithData:data];
return result;
dispatch_async(dispatch_get_main_queue(), ^{
//code for operation after download
});
});
}
Let me know how it goes

NSURLConnection didReceiveData not loading data

I'm trying to get data from a website to display it inside a table view
My code:
-(void)loadTutorials {
NSURL *url = [NSURL URLWithString:[#"http://www.example.com/search?q=" stringByAppendingString:self.searchString]];
NSURLRequest *UrlString = [[NSURLRequest alloc] initWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:UrlString
delegate:self];
[connection start];
NSLog(#"Started");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
TFHpple *tutorialsParser = [TFHpple hppleWithHTMLData:data];
NSString *tutorialsXpathQueryString = #"//div[#id='header']/div[#class='window']/div[#class='item']/div[#class='title']/a";
NSArray *tutorialsNodes = [tutorialsParser searchWithXPathQuery:tutorialsXpathQueryString];
NSMutableArray *newTutorials = [[NSMutableArray alloc] init];
for (TFHppleElement *element in tutorialsNodes) {
Data *tutorial = [[Data alloc] initWithTitle: [[element firstChild] content]
Url: [#"http://www.example.com" stringByAppendingString: [element objectForKey:#"href"]]
];
[newTutorials addObject:tutorial];
}
_objects = newTutorials;
[self.tableView reloadData];
}
but the data is not showing up, is the data not finished loading?
I got it to working without NSURLConnection but then it will stop the program until the data is recieved
According to NSURLConnectionDataDelegate
connection:didReceiveData:
is called in a incrementally manner.
The newly available data. The delegate should concatenate the contents
of each data object delivered to build up the complete data for a URL
load.
So this means you should append new data within this method.
Then, in
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
you should manipulate your data.
So, for example
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// Create space for containing incoming data
// This method may be called more than once if you're getting a multi-part mime
// message and will be called once there's enough date to create the response object
// Hence do a check if _responseData already there
_responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data
[_responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// Parse the stuff in your instance variable now
}
Obviously you should also implement the delegate responsible for error handling.
A simple note is the following. If data is too big and you need to do some computations stuff (e.g. parsing), you could block the UI. So, you could move the parsing in a different thread (GCD is your friend). Then when finished you could reload the table in the main thread.
Take a look also here for further info: NSURLConnectionDataDelegate order of functions.

defunct NSURLConnection never executes or times out

I'm running a LOT of asynchronous (delegate, not block) NSURLConnections simultaneously, and they all come back very quickly as I'm hitting a LAN server.
Every so often, one NSURLConnection will go defunct and never return.
connection:willSendRequest: is called but connection:didReceiveResponse: (and failure) is not.
Any ideas? I'm wondering if I should make a simple drop-in replacement using CFNetwork instead.
Edit: There's really not much code to show. What I've done is created a wrapper class to download files. I will note that the problem happens less when I run the connection on a separate queue - but still happens.
The general gist of what I'm doing is creating a download request for each cell as a tableview scrolls (in cellForRowAtIndexPath) and then asynchronously loading in an image file to the table cell if the cell is still visible.
_request = [NSMutableURLRequest requestWithURL:_URL];
_request.cachePolicy = NSURLRequestReloadIgnoringCacheData;
_request.timeoutInterval = _timeoutInterval;
if(_lastModifiedDate) {
[_request setValue:[_lastModifiedDate RFC1123String] forHTTPHeaderField:#"If-Modified-Since"];
}
_connection = [[NSURLConnection alloc] initWithRequest:_request
delegate:self
startImmediately:NO];
[_connection start];
As requested, instance variables:
NSMutableURLRequest *_request;
NSURLConnection *_connection;
And delegate methods:
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
NSLog(#"%# send", _URL);
return request;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"%# response", _URL);
_response = (id)response;
// create output stream
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
_receivedLength += data.length;
_estimatedProgress = (Float32)_receivedLength / (Float32)_response.expectedContentLength;
[_outputStream write:data.bytes maxLength:data.length];
// notify delegate
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// close output stream
// notify delegate
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"%# failure", _URL);
// notify delegate
}
- (void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if(_credential && challenge.previousFailureCount == 0) {
[[challenge sender] useCredential:_credential forAuthenticationChallenge:challenge];
}
}
After poking around in profiler, I found a lead, and it gave me a hunch.
My credentials were failing (not sure why...) and so previousFailureCount was not 0, and hence I wasn't using my credential object.
Changed the code to this and I have no problems:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if(_credential) {
[[challenge sender] useCredential:_credential forAuthenticationChallenge:challenge];
}
}
A NSURLConnection will send either didReceiveResponse or didFailWithError.
Often, you're dealing with timeouts before didFailWithError occurs.

iOS NSURLConnection not downloading files from certain URLs

I have an NSURLConnection in a tableview cell subclass that can download most files. I noticed, however, that some fail to start downloading, and time out. An example would be this URL, which is just a test zip file that downloads fine in any other browser. Heres my code for the download
-(void)downloadFileAtURL:(NSURL *)url{
self.downloadedData = [[NSMutableData alloc] init];
self.url = url;
conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:self.url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1200.0] delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response
{
int statusCode = [response statusCode];
if (statusCode == 200){
self.fileName.text = response.URL.lastPathComponent;
self.respo = response;
expectedLength = [response expectedContentLength];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
CFStringRef mimeType = (__bridge CFStringRef)[_respo MIMEType];
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL);
CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);
NSString *fileName = [NSString stringWithFormat:#"%#.%#", [[_respo suggestedFilename] stringByDeletingPathExtension], (__bridge NSString *)extension];
[[NSFileManager defaultManager] createFileAtPath:[[self docsDir] stringByAppendingPathComponent:[NSString stringWithFormat:#"Downloads/%#", fileName]] contents:_downloadedData attributes:nil];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"Download failed with error: %#", error);
}
Anybody see anything that might cause this?
Heres the error:
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x1fd2c650
{NSErrorFailingURLStringKey=http://download.thinkbroadband.com/10MB.zip,
NSErrorFailingURLKey=http://download.thinkbroadband.com/10MB.zip,
NSLocalizedDescription=The request timed out., NSUnderlyingError=0x1fdc90b0 "The request timed out."}
"I have an NSURLConnection in a tableview cell subclass " - never do this. As Sung-Pil Lim already pointed out correctly, TableView Cells will be reused which may cause this issue.
Anyway, the response data of your connection is a property of the model. The model might encapsulate how it gets to this data. If that data is not immediately available once it will be accessed, it should provide a "placeholder" value instead and start an asynchronous task which retrieves this data.
Suppose a model's property, an image, will be accessed by the view controller in order to be displayed by a view. The model has not yet loaded its actual image - and thus it returns a "placeholder image" in order to let the view display something. But at the same time the model is starting an asynchronous task to load the image. When this connection is finished loading with the data, the model updates internally its property - thereby replacing the placeholder with the real image. The update of the property should be performed on the main thread - since the UIKit views may access the same property as well.
During initialization, the View Controller has registered as an observer of the model's property (see KVO). When the model's property is updated, the controller gets notified. The View Controller then performs appropriate actions so that the view will be redrawn and displays the new updated value.
Your model should have a "cancel" method, which will be send to the model from the controller when the actual value of the model's property is not required anymore. For example, the user switched to another view (see viewWillDisappear).
I tried your codes.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.downloadedData appendData:data];
NSLog(#"%d", data.length);
}
2013-05-04 01:51:13.811 SomethingTodo[2732:c07] 1124
2013-05-04 01:51:13.856 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:14.075 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:17.180 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:17.295 SomethingTodo[2732:c07] 1448
It's working... on ViewController
'request timeout error' was brought to network connection. or...
Are you resuing UITableViewCell? If you initialize for cell reuse codes deal with connection. maybe bring to trouble. Just i thought.
If you attach more your codes. Could I help you more then this.
I would start with a clean slate and just use basic code to work the download. Load in lots of NSLog(s) to track everything. If that works, keep adding your custom code and see if you stumble across an error. I suggest basic NSURLConnection code:
-(void)startDownloading:(NSString *)URLaddress{
NSLog(#"start downloading from: %#",URLaddress);
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:[URLaddress stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
__unused NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"didReceiveResponse: %#", response);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"didReceiveData");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"Connection failed! Error - %# %#",[error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"connectionDidFinishLoading");
}
try with HCDownloadViewController and you can check which url is not downloaded. and next time sync for that particular url which is not downloaded.
.h file
#import "HCDownloadViewController.h"
#interface HomeViewController_iPhone : UIViewController<HCDownloadViewControllerDelegate>
{
HCDownloadViewController *tblDownloadHairStyle;
}
#property (nonatomic,retain) HCDownloadViewController *tblDownloadHairStyle;
.m file
#define kAppDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
#synthesize tblDownloadHairStyle
- (void)viewDidLoad
{
[super viewDidLoad];
tblDownloadHairStyle=[[HCDownloadViewController alloc] init];
tblDownloadHairStyle.delegate=self;
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response
{
[self createDocumentDirectory:#"Downloaded_HairStyle"];
NSString *pathHair=[self getDocumentDirectoryPath:#"Downloaded_HairStyle"];
tblDownloadHairStyle.downloadDirectory = pathHair;
////You can put url in for loop, it create queue for downloading.
[tblDownloadHairStyle downloadURL:[NSURL URLWithString:#"yourUrl"] userInfo:YourResponseDictonary];
}
-(void)createDocumentDirectory:(NSString*)pStrDirectoryName
{
NSString *dataPath = [self getDocumentDirectoryPath:pStrDirectoryName];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:NULL];
}
-(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
NSString *strPath = #"";
if(pStrPathName)
strPath = [[kAppDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];
return strPath;
}
#pragma mark-
#pragma mark-HCDownloadViewController Delegate Method
- (void)downloadController:(HCDownloadViewController *)vc startedDownloadingURL:(NSURL *)url userInfo:(NSDictionary *)userInfo {
}
- (void)downloadController:(HCDownloadViewController *)vc finishedDownloadingURL:(NSURL *)url toFile:(NSString *)fileName userInfo:(NSDictionary *)userInfo {
if (vc==tblDownloadHairStyle) {
if ([tblDownloadHairStyle numberOfDownloads]==0) {
NSLog(#"AllDownLoad are complete");
}
}
}
- (void)downloadController:(HCDownloadViewController *)vc failedDownloadingURL:(NSURL *)url withError:(NSError *)error userInfo:(NSDictionary *)userInfo {
NSLog(#"failedDownloadingURL=%#",url);
}
https://github.com/H2CO3/HCDownload
accept any response with http response code range 200-299 and disable caching on the http-connector.
double check your url address conforms to RFC 2396. so it must include HTTP://
Do you have any libraries (TestFlight, UA, etc) in the project? Try removing them and re-test. We had an app that used NSUrlConnection with TestFlight SDK that caused all sorts of sporadic network problems.
NSURLConnection timing out
ASIHTTPRequest request times out
https://github.com/AFNetworking/AFNetworking/issues/307

In iOS, how can I load modal window with the data received from some NSURLConnection?

In my iPad application, I want to load a modal window with some data.
But those data can be retrieved from a web service call. So, I have created another class and in that class's connectionDidFinishLoading I can have the response data. As the web service call is asynchronous, I have to wait for the data to load the modal window. Can anyone help me with some example code? Should I think in different way?
Thank you all for the prompt reply.
My problem was solved using the NSNotificationCenter. This tutorial was helpful http://www.youtube.com/watch?v=WB-QCv_4ANU&feature=plcp
Either you can load modal window from connectionDidFinishLoading method. Or you can use delegates to pass data from connectionDidFinishLoading metod to the window that you are going to present. Refer this tutorial.
You start the connection this way:
NSURL *url = [NSURL URLWithString:<#your url string#>];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
myData = [[NSMutableData alloc] init];
con = [[NSURLConnection alloc] initWithRequest:request delegate:self];
And you need to implement NSURLConnectionDelegate delegate.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//append data to your NSMutableData object
[myData appendData: data];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
//handle the error
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//here you can use your NSMutableData object, fill your window with the data etc.
<#your code#>
}
This is just an example. You can read more about it in NSURLConnectionDelegate Protocol Reference.

Resources