I'm using the camera view as a barcode scanner that scans a barcode and launches a segue to another viewcontroller with a webview. This is working fine, and I can navigate back to the scanner from the webview and scan another barcode without issue. However, if I navigate away from the view controller with the camera and return to it, the camera view loads but no longer detects barcodes.
#implementation ProductScanViewController
NSString *loadUrl;
AVCaptureSession *_captureSession;
AVCaptureDevice *_videoDevice;
AVCaptureDeviceInput *_videoInput;
AVCaptureVideoPreviewLayer *_previewLayer;
BOOL _running;
AVCaptureMetadataOutput *_metadataOutput;
#synthesize mWebView;
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:loadUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{if([data length] > 0 && error == nil)[mWebView loadRequest:request]; else if (error != nil) NSLog(#"Error: %", error);}
];
[self setupCaptureSession];
}
- (void)setupCaptureSession {
// 1
if (_captureSession){
return;
}
// 2
_videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (!_videoDevice) {
return;
}
// 3
_captureSession = [[AVCaptureSession alloc] init];
// 4
_videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_videoDevice error:nil];
// 5
if ([_captureSession canAddInput:_videoInput]) {
[_captureSession addInput:_videoInput];
}
// 6
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
// capture and process the metadata
_metadataOutput = [[AVCaptureMetadataOutput alloc] init];
dispatch_queue_t metadataQueue =
dispatch_queue_create("com.1337labz.featurebuild.metadata", 0);
[_metadataOutput setMetadataObjectsDelegate:self
queue:metadataQueue];
if ([_captureSession canAddOutput:_metadataOutput]) {
[_captureSession addOutput:_metadataOutput];
}
}
#pragma mark - Delegate functions
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
fromConnection:(AVCaptureConnection *)connection {
[metadataObjects enumerateObjectsUsingBlock:^(AVMetadataObject *obj,
NSUInteger idx,
BOOL *stop) {
if ([obj isKindOfClass: [AVMetadataMachineReadableCodeObject class]]) {
//NSLog(#"Capture Output started");
// 3
AVMetadataMachineReadableCodeObject *code = (AVMetadataMachineReadableCodeObject*)
[_previewLayer transformedMetadataObjectForMetadataObject:obj];
// 4
Barcode * barcode = [Barcode processMetadataObject:code];
for (NSString * str in self.allowedBarcodeTypes) {
if([barcode.getBarcodeType isEqualToString:str]){
[self validBarcodeFound:(barcode)];
return;
}
}
}
}];
}
- (void) validBarcodeFound:(Barcode *)barcode{
NSLog(#"Found Barcode");
[self stopRunning];
[self.foundBarcodes addObject:barcode];
//[self showBarcodeAlert:barcode];
NSString *alertMessage = #"";
alertMessage = [alertMessage stringByAppendingString:[barcode getBarcodeType]];
NSLog([barcode getBarcodeData]);
NSLog(alertMessage);
NSLog([NSString stringWithFormat:#"%#", barcode.getBarcodeData]);
if ([barcode.getBarcodeType isEqualToString:#"org.iso.QRCode"])
{
if ([[NSString stringWithFormat:#"%lu",(unsigned long)[self.foundBarcodes count]-1] length] > 0){
NSString *input = [barcode getBarcodeData];
[NSString stringWithFormat:#"%lu",(unsigned long)[self.foundBarcodes count]-1];
NSLog(input);
if ([input length] >= 13)
{
input = [input substringToIndex:12];
}
loadUrl = [[#"http://www.mywebsite.co.uk/" stringByAppendingString:input] stringByAppendingString:#"?utm_source=iphone"];
NSLog(loadUrl);
dispatch_sync(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"toWebView" sender:self];
});
}
}
So I've managed to fix this but can't give any real understanding of why it works.
Instead of loading the URL asynchronously during viewDidLoad, I passed the URL with the segue and loaded it from within the ViewController containing the WebView.
Further to this, the variable declarations were encapsulated in curly brackets {} and the #synthesize mWebView was removed. I've no idea why that was causing issues so any possible explanation would be appreciated
Related
I'm trying to implement capture image and videos from my app, and now from iOS 10 onward "AVCaptureStillImageOutput" is deprecated.
Please help me to implement AVCapturePhotoOutput in Objective-C.
Here is my sample code:
_avCaptureOutput = [[AVCapturePhotoOutput alloc]init];
_avSettings = [AVCapturePhotoSettings photoSettings];
AVCaptureSession* captureSession = [[AVCaptureSession alloc] init];
[captureSession startRunning];
AVCaptureConnection *connection = [self.movieOutput connectionWithMediaType:AVMediaTypeVideo];
if (connection.active)
{
//connection is active
NSLog(#"Connection is active");
id previewPixelType = _avSettings.availablePreviewPhotoPixelFormatTypes.firstObject;
NSDictionary *format = #{(NSString*)kCVPixelBufferPixelFormatTypeKey:previewPixelType,(NSString*)kCVPixelBufferWidthKey:#160,(NSString*)kCVPixelBufferHeightKey:#160};
_avSettings.previewPhotoFormat = format;
[_avCaptureOutput capturePhotoWithSettings:_avSettings delegate:self];
}
else
{
NSLog(#"Connection is not active");
//connection is not active
//try to change self.captureSession.sessionPreset,
//or change videoDevice.activeFormat
}
_avCaptureOutput = [[AVCapturePhotoOutput alloc]init];
_avSettings = [AVCapturePhotoSettings photoSettings];
AVCaptureSession* captureSession = [[AVCaptureSession alloc] init];
[captureSession startRunning];
[self.avCaptureOutput capturePhotoWithSettings:self.avSettings delegate:self];
self must implement the AVCapturePhotoCaptureDelegate
#pragma mark - AVCapturePhotoCaptureDelegate
-(void)captureOutput:(AVCapturePhotoOutput *)captureOutput didFinishProcessingPhotoSampleBuffer:(CMSampleBufferRef)photoSampleBuffer previewPhotoSampleBuffer:(CMSampleBufferRef)previewPhotoSampleBuffer resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings bracketSettings:(AVCaptureBracketedStillImageSettings *)bracketSettings error:(NSError *)error
{
if (error) {
NSLog(#"error : %#", error.localizedDescription);
}
if (photoSampleBuffer) {
NSData *data = [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:photoSampleBuffer previewPhotoSampleBuffer:previewPhotoSampleBuffer];
UIImage *image = [UIImage imageWithData:data];
}
}
Now, you get the image, and do whatever you want.
Note: Since iOS 11, -captureOutput:didFinishProcessingPhotoSampleBuffer:... is deprecated, need to use -captureOutput:didFinishProcessingPhoto:error: instead:
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(nullable NSError *)error
{
NSData *imageData = [photo fileDataRepresentation];
UIImage *image = [UIImage imageWithData:data];
...
}
I've read lots of posts regarding this problem but I couldn't get the callback delegate to work...
I've read that delegate cannot be in a background Thread or it won't get called. I think that this may be the issue... but... well let me put some code here to explain better my problem and see what you guys think.
in main thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
#try {
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:[object valueForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset)
{
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];//this is NSData may be what you want
//[data writeToFile:photoFile atomically:YES];//you can save image later
UIImage *image = [UIImage imageWithData:data];
CGFloat compression = 0.9f;
CGFloat maxCompression = 0.5f;
int maxFileSize = 1280*720; //ou usar 40960 = 40MB ?
NSData *imageData = UIImageJPEGRepresentation(image, compression);
while ([imageData length] > maxFileSize && compression > maxCompression)
{
compression -= 0.1;
imageData = UIImageJPEGRepresentation(image, compression);
}
NSString *guid = [self.idMediasAvailable lastObject];
//NSString *guid = [[NSUUID UUID] UUIDString];
NSString *boundary = #"-endUploadBoundary-";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[client addBlobToContainer:[container objectAtIndex:self.mycontainerIndex] blobName:[NSString stringWithFormat:#"%#.jpg", guid] contentData:imageData contentType:contentType ];
[uploadedMediaID setObject:object forKey:guid];
[confirmMedias addObject:guid];
[listUploadedMedias addObject:object];
[self.idMediasAvailable removeLastObject];
// [allUploadedLock lock];
// [allUploadedLock unlockWithCondition:0];
}
failureBlock:^(NSError *err) {
NSLog(#"Error: %#",[err localizedDescription]);
[allUploadedLock lock];
[allUploadedLock unlockWithCondition:0];
}];
}
#catch (NSException *exception) {
NSLog(#"Error uploadMedia: %#",[object valueForKey:UIImagePickerControllerReferenceURL]);
}
});
[allUploadedLock lockWhenCondition:0];
[allUploadedLock unlock];
this is the addToBlobContainer selector:
- (void)addBlobToContainer:(BlobContainer *)container blobName:(NSString *)blobName contentData:(NSData *)contentData contentType:(NSString*)contentType withBlock:(void (^)(NSError*))block
{
CloudURLRequest* request = nil;
if(_credential.usesProxy)
{
request = [_credential authenticatedRequestWithEndpoint:#"/SharedAccessSignatureService/blob" forStorageType:#"blob" httpMethod:#"PUT" contentData:contentData contentType:contentType, #"x-ms-blob-type", #"BlockBlob", nil];
}
else
{
NSString* containerName = [container.name lowercaseString];
NSString* endpoint = [NSString stringWithFormat:#"/%#/%#", [containerName URLEncode], [blobName URLEncode]];
request = [_credential authenticatedRequestWithEndpoint:endpoint forStorageType:#"blob" httpMethod:#"PUT" contentData:contentData contentType:contentType, #"x-ms-blob-type", #"BlockBlob", nil];
}
[request fetchNoResponseWithBlock:^(NSError* error)
{
if(error)
{
if(block)
{
block(error);
}
else if([(NSObject*)_delegate respondsToSelector:#selector(storageClient:didFailRequest:withError:)])
{
[_delegate storageClient:self didFailRequest:request withError:error];
}
return;
}
if(block)
{
block(nil);
}
else if([(NSObject*)_delegate respondsToSelector:#selector(storageClient:didAddBlobToContainer:blobName:)])
{
[_delegate storageClient:self didAddBlobToContainer:container blobName:blobName];
}
}];
}
no breakpoint is hit inside the block [request fetchNoResponseWithBlock:ˆ(NSError *error) ...];
and this is the fetchNoResponseWithBlock:ˆ selector:
- (void) fetchNoResponseWithBlock:(noResponseBlock)block {
_noResponseBlock = [block copy];
[NSURLConnection connectionWithRequest:self delegate:self];
}
and in this same file I have the delegate selectors
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
and none of these are hit as well... btw the interface declaration is #interface CloudURLRequest : NSMutableURLRequest
Ok now the strange thing is that the breakpoints inside the delegate selectors
are hit when the page is opened and another request is made to get the Blob Containers... but when I try to send a file the file is sent and there is no callback! (I manually check the blob and it uploaded successfully)
I think that when I do this:
[assetLibrary assetForURL:[object valueForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {
is this block running on a background thread by any chance? or Any suggestions?
I do need the callback to work because I have to unlock a NSLock only when the file completes the upload.
Thanks a lot in advance!
I am trying to get latest data from a RSS URL and show its content in Today Widget extension , with RSSParser but the problem is it returns null ! here is my codes :
- (void)viewDidLoad {
[super viewDidLoad];
NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://myBlog.net/?feed=rss2"]];
[RSSParser parseRSSFeedForRequest:req success:^(NSArray *feedItems) {
[self setDataSource:feedItems];
} failure:^(NSError *error) {
[self setTitle:#"Error"];
NSLog(#"Error: %#",error);
}];
item = [self.dataSource objectAtIndex:0];
//this returns null:
NSLog(#"Title is %#",[item title]);
NSLog(#"Widget Runs");
}
Not familiar with the library, but the call pattern is familiar enough to assume that the request runs asynchronously. That means that one's normal assumption that code executes top to bottom doesn't hold.
- (void)viewDidLoad {
[super viewDidLoad];
NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://myBlog.net/?feed=rss2"]];
[RSSParser parseRSSFeedForRequest:req success:^(NSArray *feedItems) {
// this runs after the request completes
NSLog(#"Got here #2");
// moving your test code here will allow it to work
item = [self.dataSource objectAtIndex:0];
NSLog(#"Title is %#",[item title]);
} failure:^(NSError *error) {
[self setTitle:#"Error"];
NSLog(#"Error: %#",error);
}];
// this runs before the request begins
NSLog(#"Got here #1");
}
I have a view controller, that loads some an array. While everything is loading, I need to present another view controller (with the UIProgressView) and update it's UI (the progress property of a UIProgressView) and then dismiss and present first vc with downloaded data. I'm really struggling on it and I've tried delegation, but nothing worked for me.
- (void)viewDidLoad
{
[super viewDidLoad];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"downloaded"]) {
} else {
NSLog(#"First time Launched");
ProgressIndicatorViewController *progressVC = [ProgressIndicatorViewController new];
progressVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self syncContacts];
[self presentViewController:progressVC animated:YES completion:nil];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"downloaded"];
[progressVC release];
}
}
sync contacts method:
- (void)syncContacts
{
NSLog(#"Sync data");
NSMutableArray *allContacts = [ContactsOperations getAllContactsFromAddressBook];
NSInteger allContactsCount = [allContacts count];
if (allContactsCount > 0) {
for (ContactData *contact in allContacts) {
NSMutableArray *phoneNumbersArray = [[NSMutableArray alloc] init];
NSString *nospacestring = nil;
for (UserTelephone *tel in [contact.abonNumbers retain]) {
NSArray *words = [tel.phoneNumber componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceCharacterSet]];
NSString *nospacestring = [words componentsJoinedByString:#""];
[phoneNumbersArray addObject:nospacestring];
}
contact.abonNumbers = phoneNumbersArray;
if (phoneNumbersArray != nil) {
NSLog(#"NOT NULL PHONENUMBERS: %#", phoneNumbersArray);
}
NSDictionary *dataDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:contact.abonNumbers, #"phoneNumbers", contact.contactName, #"fullName", [NSNumber numberWithBool:contact.isBlackList], #"blacklist", [NSNumber numberWithBool:contact.isIgnore], #"ignore", contact.status, #"status", nil];
NSLog(#"dictionary: %#", dataDictionary);
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:dataDictionary options:0 error:&error];
NSLog(#"POST DATA IS : %#", postData);
NSMutableURLRequest *newRequest = [self generateRequest:[[NSString stringWithFormat:#"%#c/contacts%#%#", AVATATOR_ADDR, SESSION_PART, [[ServiceWorker sharedInstance] SessionID]] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding] withHTTPMethod:#"POST"];
[newRequest setHTTPBody:postData];
[newRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
//__block NSMutableData *newData;
[NSURLConnection sendAsynchronousRequest:newRequest queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (!connectionError) {
NSDictionary *allData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"alldata from contacts: %#", allData);
//NSInteger errorCode = [[allData objectForKey:#"CommandRes"] integerValue];
//if (errorCode == 0) {
NSInteger remoteId = [[allData objectForKey:#"contactId"] integerValue];
contact.remoteId = remoteId;
NSLog(#"remote id is from parse content : %d", remoteId);
[[AvatatorDBManager getSharedDBManager]createContactWithContactData:contact];
} else {
NSLog(#"error");
}
}];
//Somewhere here I need to update the UI in another VC
[phoneNumbersArray release];
[dataDictionary release];
}
} else {
}
}
generate request method:
- (NSMutableURLRequest *)generateRequest:(NSString *)urlString withHTTPMethod:(NSString *)httpMethod
{
NSLog(#"url is :%#", urlString);
NSURL *url = [NSURL URLWithString:urlString];
request = [NSMutableURLRequest requestWithURL:url];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[request setHTTPMethod:httpMethod];
return request;
}
ProgressViewController is just an empty VC with the progress bar. No code yet.
In the view controller that will display the progress view expose a method like this...
- (void)updateProgress:(float)progress;
Its implementation will look like this...
- (void)updateProgress:(float)progress {
[self.progressView setProgress:progress animated:YES];
}
On the main view controller you need to execute the long-running process on a background thread. Here's viewDidLoad for the main view controller. This example code uses a property for the progress view controller (you may not require this) and assumes your are in a navigation controller...
- (void)viewDidLoad {
[super viewDidLoad];
// Create and push the progress view controller...
self.pvc = [[ProgressViewController alloc] init];
[self.navigationController pushViewController:self.pvc animated:YES];
// Your long-running process executes on a background thread...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Your long-running process goes here. Wherever required you would
// call updateProgress but that needs to happen on the main queue...
dispatch_async(dispatch_get_main_queue(), ^{
[self.pvc updateProgress:progress];
});
// At the end pop the progress view controller...
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
});
}
I'm trying to create a simple rss reader. The code works okay, except the UI hangs when the feeds are being updated. I thought I cobbled together the code to get the feed and parse it on a background queue while updating the UI on the mainQueue, but the table hangs pretty badly. Code below:
-(void)refreshFeed2
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (NSString *feed in _feeds) {
// iterate over all feeds
NSLog(#"feed=%#", feed);
NSURL *url = [NSURL URLWithString:feed];
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(void)[conn initWithRequest:request delegate:self];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] == 0 && error == nil) {
// handle empty response
} else if (error != nil) {
// handle error
NSLog(#"Error %#", [error localizedDescription]);
} else if ([httpResponse statusCode] == 200) {
// data present and no errors
[queue addOperationWithBlock:^{
// parse feed on queue
RXMLElement *rss = [RXMLElement elementFromXMLData:data];
RXMLElement *rssChild = [rss child:#"channel"];
RXMLElement* title = [rssChild child:#"title"];
NSArray* items = [[rss child:#"channel"] children:#"item"];
NSMutableArray* result=[NSMutableArray array];
for (RXMLElement *e in items) {
// iterate over the articles
RSSArticle* article = [[RSSArticle alloc] init];
article.sourceTitle = [title text];
article.articleTitle = [[e child:#"title"] text];
article.articleDescription = [[e child:#"description"] text];
article.articleUrl = [NSURL URLWithString: [[e child:#"link"] text]];
NSString *articleDateString = [[e child:#"pubDate"] text];
article.articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
if (article.articleUrl != NULL) {
[result addObject:article];
}
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// update table on mainQueue
for (RSSArticle *article in result) {
// iterate over articles
int insertIdx = [_allEntries indexForInsertingObject:article sortedUsingBlock:^(id a, id b) {
RSSArticle *entry1 = (RSSArticle *) a;
RSSArticle *entry2 = (RSSArticle *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:article atIndex:insertIdx];
[self.LeftTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationFade];
}
}];
}];
}
}];
// Stop refresh control
[refreshControl endRefreshing];
}
}
Code that calls refreshFeed2:
- (void)viewDidLoad {
[super viewDidLoad];
self.allEntries = [NSMutableArray array];
self.feeds = [NSArray arrayWithObjects:
#"http://feeds.washingtonpost.com/rss/politics",
#"http://rss.cnn.com/rss/cnn_allpolitics.rss",
#"http://www.npr.org/rss/rss.php?id=1012",
#"http://www.slatedigital.com/support/feeds/rss_kb.php?s=fd5aa35e773dc3177b85a2126583f002",
nil];
}
//add refresh control to the table view
refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self
action:#selector(refreshInvoked:forState:)
forControlEvents:UIControlEventValueChanged];
NSString* fetchMessage = [NSString stringWithFormat:#"Fetching Articles"];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:fetchMessage
attributes:#{NSFontAttributeName:[UIFont fontWithName:#"Helvetica" size:11.0]}];
[self.LeftTableView addSubview: refreshControl];
[self refreshInvoked:self forState:UIControlStateNormal];
}
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
NSOperationQueue *refreshQueue = [[NSOperationQueue alloc] init];
[refreshQueue addOperationWithBlock:^{
[self refreshFeed2];
}];
}
Any help?
Thanks!
Can you try this? replace
[self refreshInvoked:self forState:UIControlStateNormal];
by
[self performSelectorOnBackground:#selector(refreshFeed2) withObject:nil];
and replace the same instead of
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
[self performSelectorOnBackground:#selector(refreshFeed2) withObject:nil ];
}