I can't get the NSMetadataQueryDidUpdateNotification to work. Been stuck at it for days. Is there something abnormal in the code below.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0ul), ^{
NSString* filePattern = [NSString stringWithFormat:#"*.%#", #"*"];
NSMetadataQuery *aQuery = [[NSMetadataQuery alloc] init];
aQuery.predicate = [NSPredicate predicateWithFormat: #"%K LIKE %#", NSMetadataItemFSNameKey, filePattern];
[aQuery setSearchScopes:#[NSMetadataQueryUbiquitousDataScope]];
[aQuery setValueListAttributes:#[NSMetadataUbiquitousItemPercentDownloadedKey, NSURLUbiquitousItemDownloadingStatusKey,NSURLUbiquitousItemIsDownloadingKey,NSURLUbiquitousItemDownloadRequestedKey]];
_query = aQuery;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(liveUpdate:)
name:NSMetadataQueryDidUpdateNotification
object:aQuery];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(initalGatherComplete:) name:NSMetadataQueryDidFinishGatheringNotification object:aQuery];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(gatherProgress:) name:NSMetadataQueryGatheringProgressNotification object:aQuery];
[aQuery enableUpdates];
dispatch_async(dispatch_get_main_queue(), ^{
[aQuery startQuery];
});
});
Hope this helps you
Try replace with this code about notification
And metadata query should be started on main queue, you did it right :)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(liveUpdate:)
name:NSMetadataQueryDidUpdateNotification
object:aQuery];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(initalGatherComplete:)
name:NSMetadataQueryDidFinishGatheringNotification
object:aQuery];
And this is example for processing gathering notification
- (void)initialGatherComplete:(NSNotification*)notification
{
//process here.
}
The solution is to strong reference the notification block as such
_notifqueryDidUpdate = [[NSNotificationCenter defaultCenter]addObserverForName:NSMetadataQueryDidUpdateNotification object:aQuery queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
[self liveUpdate:note];
}];
Related
I am using NSNotificationCenter in a code .
[[NSNotificationCenter defaultCenter]addObserverForName:#"NextIndexNotification" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self receiveTestNotification:note];
[[NSNotificationCenter defaultCenter] removeObserver:note];
}];
- (void)receiveTestNotification:(NSNotification *) notification
{
NSDictionary *userInfo = notification.userInfo;
NSString *strServerResultID = [userInfo objectForKey:#"valServerResultID"];
}
//// And I am adding Notification center here ...
dispatch_async(dispatch_get_main_queue(),^{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"%#",[[PerformXMLXPathQuery(responseData,xPathQuery) objectAtIndex:0] valueForKey:kNodeContent]] forKey:#"valServerResultID"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"NextIndexNotification" object:self userInfo:userInfo];
});
in this code , remove notification doesn't being called and my code move to infinite loop .
where am I doing wrong ?
Try
[[NSNotificationCenter defaultCenter] removeObserver:nil];
Remove notification by using blocks.
[[NSNotificationCenter defaultCenter] removeObserver:self];
Instead of passing note (which is the Notification itself, not the observer), pass the return value from the addObserverForName call to removeObserver, like this:
__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:#"NextIndexNotification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note)
{
[self receiveTestNotification:note];
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}];
I have an UIActivityIndicatorView which I start and stop on an notification which I receive from the Notification Center. Although I receive the notifications and I call the start and stop via 'performSelectorOnMainThread' it does not start animating, and does not become visible.
Here is my code:
-(void)stopAnimation:(id)sender {
if( _saveActivityIndicatorView.isAnimating ) {
[_saveActivityIndicatorView stopAnimating];
}
}
-(void)startAnimation:(id)sender {
if( !_saveActivityIndicatorView.isAnimating ) {
[_saveActivityIndicatorView startAnimating];
}
}
-(void)saveStarted{
NSLog(MRVaccinationEventsUpdateStarted);
[self performSelectorOnMainThread:#selector(startAnimation:) withObject:self waitUntilDone:YES];
}
-(void)saveCompleted{
NSLog(MRVaccinationEventsUpdateCompleted);
[self performSelectorOnMainThread:#selector(stopAnimation:) withObject:self waitUntilDone:YES];
}
And this is how I post and observe the notifications (both in the same file):
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(saveStarted)
name:MRVaccinationEventsUpdateStarted
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(saveCompleted)
name:MRVaccinationEventsUpdateCompleted
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:MRVaccinationEventsUpdateStarted object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:MRVaccinationEventsUpdateCompleted object:nil];
Note, that I DO RECEIVE the notifications.
What is wrong with this code?
This is because the start and stop animation's are in the same loop.
[[NSNotificationCenter defaultCenter] postNotificationName:MRVaccinationEventsUpdateStarted object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:MRVaccinationEventsUpdateCompleted object:nil];
You should post the second notification after some time, like
/// three seconds
delayInSeconds = 3;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[[NSNotificationCenter defaultCenter] postNotificationName:MRVaccinationEventsUpdateCompleted object:nil];
});
I am trying to do a notification from a location manager object to my viewController. It's not working - the selector in the addObserver method doesn't get called.
Location Manager Object.m files (singleton with standard dispatch once & init methods)
- (void)setCurrentLocation:(CLLocation *)currentLocation
{
if (!_location) {
_location = [[CLLocation alloc] init];
}
_location = currentLocation;
NSNumber *latitude = [NSNumber numberWithDouble:self.location.coordinate.latitude];
NSNumber *longitude = [NSNumber numberWithDouble:self.location.coordinate.longitude];
NSLog(#"lat %# & long %# in notification section", latitude, longitude);
NSNotification *notification = [NSNotification notificationWithName:#"myNotification" object:self userInfo: #{kSetLat: latitude,
kSetLong: longitude}];
[[NSNotificationCenter defaultCenter] postNotification:notification];
}
ViewController.m (garden variety)
- (IBAction)welcomeNotification:(UIButton *)sender {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(sendGetRequest:) name:#"myNotification" object:[LPLocationManager sharedManager]];
[center removeObserver:self];
NSLog(#"welcomeNotication triggered");
}
The way you do is not correct. Why you add the observer and then remove it immediately. Most of the time, we add/remove observer in viewWillAppear and viewWillDisappear or viewDidAppear and viewDidDisappear.
It should be something like:-
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sendGetRequest:) name:#"myNotification" object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"myNotification" object:nil];
}
I download one song -> it is synced on `iCloud.
I go to Setting -> iCloud -> Manage Storage -> my application to delete all files.
I go to my application and check notification from (NSMetadataQueryDidFinishGatheringNotification and NSMetadataQueryDidUpdateNotification) -> NSMetadataQuery.results return 1 item (old value)
Thank you very much in advance.
enter code here
- (void)processiCloudFiles:(NSNotification *)notification {
[_query disableUpdates];
[_iCloudNames removeAllObjects];
int totalItems = _query.resultCount; // it not update here
//OR: _query.results
}
- (void)startQuerying {
[self stopQuery];
_query = [self documentQuery];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(processiCloudFiles:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(processiCloudFiles:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
[_query startQuery];
}
- (void)stopQuery {
if (_query) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:nil];
[_query stopQuery];
_query = nil;
}
}
- (NSMetadataQuery *)documentQuery {
NSMetadataQuery * query = [[NSMetadataQuery alloc] init];
if (query) {
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSString * filePattern = [NSString stringWithFormat:#"*.%#", FILE_EXTENSION];
[query setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE %#",
NSMetadataItemFSNameKey, filePattern]];
}
return query;
}
When user presses home button, you create temp file at Document folder. Do this because user maybe go to setting device and delete song.
When user goes to you application, you can delete this temp file so that iCloud can refresh list of data.
Hope this helps you.
Is there any corner case behaviors for removeObserver:name:object:? In the following block of code, my observer isn't being registered properly:
- (void)setPlayerItem:(AVPlayerItem *)playerItem {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:nil
object:playerItem];
[playerItem addObserver:self
forKeyPath:kStatus
options:0
context:(__bridge void*)self];
[playerItem addObserver:self
forKeyPath:kPlaybackBufferEmpty
options:0
context:(__bridge void*)self]; // For adding a buffering activity indicator
id temp = playerItem_;
playerItem_ = [playerItem retain];
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
[temp removeObserver:self forKeyPath:kPlaybackBufferEmpty];
[temp removeObserver:self forKeyPath:kStatus];
[temp release];
}
However, if I change the order around to:
- (void)setPlayerItem:(AVPlayerItem *)playerItem {
[playerItem addObserver:self
forKeyPath:kStatus
options:0
context:(__bridge void*)self];
[playerItem addObserver:self
forKeyPath:kPlaybackBufferEmpty
options:0
context:(__bridge void*)self]; // For adding a buffering activity indicator
id temp = playerItem_;
playerItem_ = [playerItem retain];
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
[temp removeObserver:self forKeyPath:kPlaybackBufferEmpty];
[temp removeObserver:self forKeyPath:kStatus];
[temp release];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:nil
object:playerItem];
}
All the notifications post just fine. This leads me to believe something strange is happening when I call:
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
Am I missing something really obvious here? I'm on iOS 6 with no ARC.
Found the answer. Turns out it has to do with passing in nil for the observer name.
Calling [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
will remove self from observing any notifications posted by temp.
However, in the corner case that temp is nil, this line of code will remove self as an observer all together.
Name shouldn't be nil. Did you try giving your observer a name?
#Lee is correct that the name should not be nil but it also should not be the name of the observer. Rather it should be the name of the notification that you are registering to observe. e.g., UIDeviceOrientationDidChangeNotification.
Add the name of the notification that you want to observe in that param and also pass it as the name param when you remove observer