I want to track percentage of my uploaded file to icloud using NSMetadataQuery, but It didn't work.
This is my code :
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[fileCoordinator coordinateReadingItemAtURL:backupUrl options:NSFileCoordinatorReadingWithoutChanges error:nil byAccessor:^(NSURL *newURL) {
NSFileManager* fm = [NSFileManager defaultManager];
NSError *theError = nil;
BOOL success =[fm setUbiquitous:YES itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:#"Documents" isDirectory:true] URLByAppendingPathComponent:bName] error:&theError];
if (!(success)) {
[progView dismiss];
UIAlertView* alertFail=[[UIAlertView alloc]initWithTitle:#"Backup Error" message:#"Could not backup to iCloud." delegate:Nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertFail show];
NSLog(#"iCloud error: %#", [theError localizedDescription]);
}
else{
NSURL* destURL=[[ubiq URLByAppendingPathComponent:#"Documents" isDirectory:true] URLByAppendingPathComponent:bName];
NSMetadataQuery* query=[[NSMetadataQuery alloc]init];
[query setPredicate:[NSPredicate predicateWithFormat:#"%K > 0",NSMetadataUbiquitousItemPercentUploadedKey]];
[query setSearchScopes:#[destURL]];
[query setValueListAttributes:#[NSMetadataUbiquitousItemPercentUploadedKey,NSMetadataUbiquitousItemIsUploadedKey]];
_alertQuery=query;
[query enableUpdates];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(liveupdate:) name:NSMetadataQueryDidUpdateNotification object:query];
`// [progView dismiss];
NSLog(#"desturl %#",query);
[query startQuery];
}
}];
-(void)liveupdate:(NSNotification *)note{
NSMetadataQuery* query=[note object];
if ([query resultCount]==0)
return;
NSMetadataItem* item=[query resultAtIndex:0];
float progress=[[item valueForAttribute:NSMetadataUbiquitousItemPercentUploadedKey]floatValue];
[progView.progBar setProgress:progress animated:NO];
if ([[item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey] boolValue]){
[query stopQuery];
[query disableUpdates];
_alertQuery=nil;
[progView dismiss];
}
}
the liveUpdate:note method didn't called. can someone help me how to fix this code. thank you
i edited my code...
this is my new code
- (void)loadNotes:(NSString *)bname {
self.alertQuery = [[NSMetadataQuery alloc] init];
[self.alertQuery setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE %#", NSMetadataItemFSNameKey, bname]];
[self.alertQuery setSearchScopes:#[NSMetadataQueryUbiquitousDataScope]];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(liveupdate:) name:NSMetadataQueryDidUpdateNotification object:self.alertQuery];
[self.alertQuery startQuery];
}
-(void)liveupdate:(NSNotification *)note {
NSMetadataQuery* query=[note object];
if ([query resultCount]==0){
return;
}
NSMetadataItem* item=[query resultAtIndex:0];
float progress=[[item valueForAttribute:NSMetadataUbiquitousItemPercentUploadedKey]floatValue];
[progView.progBar setProgress:progress animated:NO];
if ([[item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey] boolValue]){
[query stopQuery];
[query disableUpdates];
_alertQuery=nil;
[progView dismiss];
}
}
it still can't call the liveupdate method.
what is the problem with my code?
Looks like you have some problems with your metadata query. First:
[query setPredicate:[NSPredicate predicateWithFormat:#"%K > 0",NSMetadataUbiquitousItemPercentUploadedKey]];
It might be that this is supposed to work, but I'm pretty skeptical of that. What you really need here is a predicate that uses the file name. If the filename is saved in an NSString named filename, something like this:
[query setPredicate:[NSPredicate predicateWithFormat:#"%K LIKE %#", NSMetadataItemFSNameKey, filename]];
That's the biggest problem. Fixing it might be all you need. But there are some other things I'd change as well. Next:
[query setSearchScopes:#[destURL]];
Again, that might be something that's supposed to work, but I've only seen good results with a much more general setting:
[query setSearchScopes:#[NSMetadataQueryUbiquitousDataScope]];
Finally:
[query setValueListAttributes:#[NSMetadataUbiquitousItemPercentUploadedKey,NSMetadataUbiquitousItemIsUploadedKey]];
This would probably work if you looked up the values directly on the query object via valueListAttributes. But I'd recommend just dropping this line completely. You can still look up the progress and status from NSMetadataItem without it.
Related
Just updated to Yosemite and Xcode 6.0.01 and this code no longer works:
- (NSImage *)songImage {
if (!_songImage) {
AVAsset *asset = [AVAsset assetWithURL:self.fileURL];
for (AVMetadataItem *metadataItem in asset.commonMetadata) {
if ([metadataItem.commonKey isEqualToString:#"artwork"]){
NSDictionary *imageDataDictionary =
(NSDictionary *)metadataItem.value;
NSData *imageData = [imageDataDictionary objectForKey:#"data"];
_songImage =[[NSImage alloc] initWithData:imageData];
}
}
}
if (!_songImage) {
return Nil;
}
return _songImage;
}
I'm not sure if the process was replaced or removed but I now get a message:
2014-10-17 14:36:23.756 FSC Music[3317:122917] -[__NSCFData objectForKey:]: unrecognized
selector sent to instance 0x600000241cb0 2014-10-17 14:36:23.764
FSC Music[3317:122917] -[__NSCFData objectForKey:]: unrecognized selector sent to instance
0x600000241cb0
need to research a solution, but wanted to ask if anyone else has come across this?
I changed to the following code to get it working again.
-(NSImage *)songImage {
if (!_songImage) {
AVAsset *asset = [AVAsset assetWithURL:self.fileURL];
NSArray *metadata = [asset commonMetadata];
for ( AVMetadataItem *item in metadata ) {
if ([item.commonKey isEqualToString:#"artwork"]){
NSData *thePix = (NSData *)item.value;
_songImage =[[NSImage alloc] initWithData:thePix];
}
}
}
if (!_songImage) {
return Nil;
}
return _songImage;
}
This is NSLog of my NSArray
[{"id":16,"venueId":16,"street":"171 - 3401 Dufferin St","city":"Toronto","zipcode":"M6A 2T9","province":"ON","country":"Canada"}]
NSDictionary *dict = [myarray objectAtIndex:i]
//myarray is your array of dictionary
//if the array has just one element like in your example, i will be 0
NSNumber *venueId = [dict objectForKey:#"venueId"];
finally I found solution
NSError *error;
NSArray* jsonArray = [NSJSONSerialization JSONObjectWithData:[[venue objectForKey:#"address"] dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error] ;
NSDictionary *dict = [jsonArray objectAtIndex:0];
//myarray is your array of dictionary
NSString *street = [dict objectForKey:#"street"];
NSLog(#"street: %#", street);
Note: I used below code to check data type to make sure it returns valid kind of class.
if ([[venue objectForKey:#"address"] isKindOfClass:[NSArray class]]) {
NSLog(#"%#", #"It is NSArray");
} else if ([[venue objectForKey:#"address"] isKindOfClass:[NSString class]]) {
NSLog(#"%#", #"It is NSString");
}
My App deals with downloading coupons & save into Passbook. But each time I download a different coupon, file is getting replaced on Passbook.
Below given is my code to add my coupons to Passbook :
Step 1 : Added 'PassKit' framework to the project & imported the same.
Step 2 : Added 'PKAddPassesViewControllerDelegate' on my h file.
Step 3 :
- (void) generatePass {
if (![PKPassLibrary isPassLibraryAvailable]) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"PassKit not available"
delegate:nil
cancelButtonTitle:#"Pitty"
otherButtonTitles: nil] show];
return;
}
else {
NSData *passData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://(url).pkpass"]];
NSError* error = nil;
PKPass *newPass = [[PKPass alloc] initWithData:passData
error:&error];
if (error!=nil) {
[[[UIAlertView alloc] initWithTitle:#"Passes error"
message:[error
localizedDescription]
delegate:nil
cancelButtonTitle:#"Ooops"
otherButtonTitles: nil] show];
return;
}
PKAddPassesViewController *addController =
[[PKAddPassesViewController alloc] initWithPass:newPass];
addController.delegate = self;
[self presentViewController:addController
animated:YES
completion:nil];
}
}
Passbook indexes passes by serialNumber and passTypeIdentifier. When adding a pass, if a pass with a matching serialNumber and passTypeIdentifier already exists in a user's pass library, that pass will be overwritten by the pass being added.
To add multiple passes for the same passTypeIdentifer you will have to generate a unique serialNumber for each new pass.
i have situation where i need to wait till one block is get completed and then only move forward with my code for that i use CFRunLooprun and stop this is how do it i will explain more things in comment in my code
[self fatchAllEvent]; // BLOCK IS IN THIS METHOD
NSLog(#"loop will start");
CFRunLoopRun();
NSLog(#"LOOP IS STOOPED");
-(void)fatchAllEvent{
events = [[NSMutableArray alloc]init];
// // Get the appropriate calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
eventStore = [[EKEventStore alloc] init];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
// __block typeof (self) weakSelf = self; // replace __block with __weak if you are using ARC
dispatch_async(dispatch_get_main_queue(), ^{
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
[events removeAllObjects];
NSLog(#" granted");
NSLog(#"User has granted permission!");
// Create the start date components
NSDateComponents *twoYearAgoComponents = [[NSDateComponents alloc] init];
twoYearAgoComponents.year = -2;
NSDate *oneDayAgo = [calendar dateByAddingComponents:twoYearAgoComponents
toDate:[NSDate date]
options:0];
// Create the end date components
NSDateComponents *twoYearFromNowComponents = [[NSDateComponents alloc] init];
twoYearFromNowComponents.year = 2;
NSDate *oneYearFromNow = [calendar dateByAddingComponents:twoYearFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:oneDayAgo
endDate:oneYearFromNow
calendars:nil];
// Fetch all events that match the predicate
events =(NSMutableArray*) [eventStore eventsMatchingPredicate:predicate];
NSLog(#"The content of array is%#",events);
}
else
{
NSLog(#"Not granted");
}
NSLog(#"LOOP WILL STOP"); // THIS GETS PRINT
CFRunLoopStop(CFRunLoopGetCurrent()); // BUT LOOP IS NOT STOPPING HERE SO MY APP JUST GET HANGED ;
}];
});
}
else
{
[events removeAllObjects];
NSLog(#"Autometiclly granted permission!");
// Create the start date components
NSDateComponents *twoYearAgoComponents = [[NSDateComponents alloc] init];
twoYearAgoComponents.year = -2;
NSDate *oneDayAgo = [calendar dateByAddingComponents:twoYearAgoComponents
toDate:[NSDate date]
options:0];
// Create the end date components
NSDateComponents *twoYearFromNowComponents = [[NSDateComponents alloc] init];
twoYearFromNowComponents.year = 2;
NSDate *oneYearFromNow = [calendar dateByAddingComponents:twoYearFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:oneDayAgo
endDate:oneYearFromNow
calendars:nil];
// Fetch all events that match the predicate
events =(NSMutableArray*) [eventStore eventsMatchingPredicate:predicate];
NSLog(#"The content of array is%#",events);
}
}
You can't do that this way - you have to call your function, and then in the completion block of the async dispatch, at the end, call a function that continues with what you want to do.
In your above code you mix up asynchronous programming with synchronous execution, that won't work.
I've an array (tempList) populated with records read from a sqlite data source. I want to sort these records based on 'region'. So I've set up the following NSMUtableArrays: _Asia, _Africa, _CentralAmerica, _southAmerica.
The method compiles without any errors. Where the 'if' statements return true, it executes the 'addObject' but the element is not added to the array.
- (void) sortIntoRegions: tempList
{
for (beans *arrayElement in tempList) {
NSLog(#"region: %#", arrayElement.region);
if ([arrayElement.region isEqualToString:#"Africa"]) {
[_africa addObject:arrayElement.name];
} else if ([arrayElement.region isEqualToString: #"Asia & South Pacific"]) {
[_asia addObject:arrayElement.name];
}
else if ([arrayElement.region isEqualToString: #"Central America"]) {
[_centralAmerica addObject:arrayElement];
} else if ([arrayElement.region isEqualToString: #"South America"]) {
[_southAmerica addObject:arrayElement];
}
}
}
I'm going to go out on a limb and guess that you have declared _africa, _asia, _centralAmerica, and _southAmerica to be NSMutableArray *, but you have not initialized them. That is, you have not written any code like this:
_africa = [[NSMutableArray alloc] init];
_asia = [[NSMutableArray alloc] init];
_centralAmerica = [[NSMutableArray alloc] init];
_southAmerica = [[NSMutableArray alloc] init];
Your instance variables are set to nil when your object is created. Sending a message (like addObject:) to nil has no effect (and doesn't print a warning or error message).