Run assetlibrary code without needing to use current location? - iphone

When i run the following code:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:albumCopy
resultBlock:^(ALAsset *asset) {
...
}
failureBlock:^(NSError *error) {
...
}];
[library autorelease];
the app asks the user for permission to use their current location. I don't use their current location in any way, so is there a way to stop it from asking the user? I know those messages always detract from the user experience.

Thats not possible, Apple did this because the EXIF data of the photos contains the location and they don't have a way to request everything but the location tag from the photos. File a bug report, maybe they will implement something like this in a future iOS version.

Related

Launching the app store dialog box?

I just noticed in iOS 6 that in your default Mail app, if you tap an itunes URL, an app store dialog box actually opens displaying the app's details.
There's no redirect to the app store! This box shows the screenshots, descriptions, etc. as if you were already in the app store.
I'm wondering if its possible to launch this box from inside my own app. I currently use itms-apps:// which naturally leaves my app, and goes to the app store.
If you are developing for iOS 6+ only, you can use SKStoreProductViewController.
Something like this:
SKStoreProductViewController *storeViewController =
[[SKStoreProductViewController alloc] init];
storeViewController.delegate = self;
NSDictionary *parameters =
#{SKStoreProductParameterITunesItemIdentifier:
[NSNumber numberWithInteger:333700869]}; //Identifier of the item you want to buy.
[storeViewController loadProductWithParameters:parameters
completionBlock:^(BOOL result, NSError *error) {
if (result)
[self presentViewController:storeViewController
animated:YES
completion:nil];
}];
(Code from this tutorial.)

MPMediaPickerController.showsCloudItems seems to do nothing

Posted this on Apple with no luck, but now that the iOS 6 NDA is up, hoping more eyes will see it here.
I am attempting to modify an app to only allow a user to select music that has been downloaded locally. I have the following code under iOS 6 GM:
MPMediaPickerController* mpc = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
mpc.allowsPickingMultipleItems = YES;
mpc.modalPresentationStyle = UIModalPresentationCurrentContext;
mpc.showsCloudItems = NO;
[self presentViewController:mpc animated:YES completion:nil];
From the documentation:
The default behavior for a media item picker is YES, which means the
the picker shows available iCloud items. A media item is considered an
iCloud item if it is available via iTunes Match and is not already
stored on the device.
I take this to mean that if iTunes Match is enabled, only items that have been downloaded to the device will show in the picker, however I always see the entire iTunes Match library. I filed a radar for this, because it seems like a serious bug. If anyone can tell me otherwise, I'd love to know what I'm missing here.
This seems to be an OS problem.
Using picker.showsCloudItems = NO; correctly shows fewer songs, instead of the whole list... The songs listed there are songs that either were manually downloaded in the Music app or songs that were streamed and therefore cached.
The problem, at least in my case, is dealing with the cached ones.
If I select a song that was manually downloaded the value of MPMediaItemPropertyIsCloudItem is NO, which is correct. I can also access the asset's URL through the MPMediaItemPropertyAssetURL property.
On the other hand, selecting a song that was cached returns YES on MPMediaItemPropertyIsCloudItem and nil on MPMediaItemPropertyAssetURL, making the song virtually useless to me.
Sorry I don't have an actual answer but I don't have enough reputation to simply comment.
Hope my 2 cents help somehow, but it truly seems to me that this issue can only be resolved by Apple in a future update.
A better solution to test if an item comes from iCloud in the didPickMediaItems delegate:
MPMediaItem *selectedItem = [selectedItems objectAtIndex:0];
if (![[selectedItem valueForProperty:MPMediaItemPropertyIsCloudItem] boolValue])
You don't really need to play it, it is more efficient to use the embedded property in the MPMediaItem.
I had this same problem. Although I was unable to hide the items, here's a good workaround that I used to prevent people from being able to select them. Inside didPickMediaItems, you should temporarily load it into an AVPlayerItem and then just check the validity of that item like so:
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
MPMediaItem *selectedItem = [[mediaItemCollection items]objectAtIndex:0];
NSURL *tempURL = [selectedItem valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithURL:tempURL];
if(playerItem.loadedTimeRanges==NULL)
{
UIAlertView *alert=[[[UIAlertView alloc]initWithTitle:NSLocalizedString(#"Invalid Song Choice",NULL) message:NSLocalizedString(#"Please choose a song that is local to your phone.",NULL) delegate:self cancelButtonTitle:NSLocalizedString(#"Okay",NULL) otherButtonTitles:nil]autorelease];
[alert show];
[playerItem release];
}
else
{
NSLog(#"Your good to go...do whatever you want with the local song");
}
}
It appears to be fixed in iOS 7.
The following code works; iCloud items are not showing:
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];
picker.delegate = self;
picker.allowsPickingMultipleItems = NO;
picker.showsCloudItems = NO;

iphone: UIImagePickerController how to get the thumbnail for the picker control

Hello I need to use the uiimagepickercontroller to get the photo from the photo library in IOS 3. I managed to get the original image and custom coding to generate the thumbnail from the original image.
Is there a way of fetching the thumbnail that was used in the UIImagePickerController? I can generate thumbnail from original image but it will slow down the whole process. At the time, is there a way of saving the url of the original image. At the moment, I am just create a new image and saved on a temporary folder for later app to upload the server. The process is too slow since I need to generate thumbnail as well as creating the original image.
in ios 3.0 , their is no direct way to get thumbnail, you have to do custom coding to get thumbnail .
from version 4.0 we have ALAssetsLibrary.
ALAssetsLibrary *assetslibrary = [self defaultAssetsLibrary];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset){
CGImageRef thumbnailRef = [myasset thumbnail]; //gives thumbnail
}
[assetslibrary assetForURL:asseturl resultBlock:resultblock failureBlock:^(NSError *error) {
//handle error
}];
but cons of above method is if used declined access to library then you have to handle error and again get thumbnail again with custom coding .
please update if you have find any better method .

How to check if iCloud is configured programmatically

Here is the sentence from Apple Docs:
"If iCloud is not configured, ask users if they want to configure it (and, preferably, transfer them to Launch Settings if they want to configure iCloud)."
How can I check if iCloud is configured or not and how to launch settings for iCloud?
Edit:
If you are targeting iOS6 or above you can use [[NSFileManager defaultManager] ubiquityIdentityToken];. For usage example please refer #Dj S' answer :).
It is faster and easier than the original solution which was meant for people targeting iOS5 and above
Original Answer
As documented in iOS App programming guide - iCloud Storage. That can be checked by asking the ubiquity container URL to the file manager :)
As long as you supply a valid ubiquity container identifier below method should return YES
- (BOOL) isICloudAvailable
{
// Make sure a correct Ubiquity Container Identifier is passed
NSURL *ubiquityURL = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:#"ABCDEFGHI0.com.acme.MyApp"];
return ubiquityURL ? YES : NO;
}
However, I've found that URLForUbiquityContainerIdentifier: might take several seconds the very first time within a session (I used it in iOS5 so things might be different now). I remember using something like this:
dispatch_queue_t backgroundQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue,^{
BOOL isAvailable = [self isICloudAvailable]
/* change to the main queue if you want to do something with the UI. For example: */
dispatch_async(dispatch_get_main_queue(),^{
if (!isAvailable){
/* inform the user */
UIAlertView *alert = [[UIAlertView alloc] init...]
[alert show];
[alert release];
}
});
});
Just to supplement the answer above,
if you only want to know if iCloud is available for your application,
e.g.
1. no iCloud account is setup, or
2. Documents and Data is disabled (for all apps), or
3. Documents and Data is disabled for your app only
then you can use NSFileManager's ubiquityIdentityToken for iOS 6 and above.
If value is nil, then iCloud account is not configured. Otherwise, iCloud account is configured.
id token = [[NSFileManager defaultManager] ubiquityIdentityToken];
if (token == nil)
{
// iCloud is not available for this app
}
else
{
// iCloud is available
}
Note that according to Apple docs, you can call it from the main thread.
Because this method returns relatively quickly, you can call it at launch time and you can call it from your app’s main thread.

iPhone: Save image to a specific photo album

The application I am working on manipulates an image for a user, and after the user is done, they can save that photo. I have no problem capturing the screen and saving it (as I want some of the labels saved with the image) but this call:
UIImageWriteToSavedPhotosAlbum([self getScreenAsImage] , nil, nil, nil);
only appears to allow me to save to the 'Saved Photos' album. Ideally I would like to create an album named after the application I am working on and save it there so that they are all stored together (for example like the Hawaii or graduation day albums on the simulator). It would also be nice then to launch the image picker in that specific album. Anyone know how to do this? Most important part is to be able to save it in an album, being able to launch the picker in that album is of secondary importance.
There is a way to do it, Apple just hasn't made it simple.
There is a custom category that adds the functionality to ALAssetsLibrary.
Git repo for the category can be found here
and if you are using Cocoapods you can get it with
pod 'ALAssetsLibrary-CustomPhotoAlbum'
You will need to instantiate a ALAssetsLibrary object and call the method below
- (void)saveImage:(UIImage *)image
toAlbum:(NSString *)albumName
completion:(ALAssetsLibraryWriteImageCompletionBlock)completion
failure:(ALAssetsLibraryAccessFailureBlock)failure
Something like below
Import:
#import "ALAssetsLibrary+CustomPhotoAlbum.h" //Source Included (Git)
or
#import <ALAssetsLibrary+CustomPhotoAlbum.h> //Cocoapods
Call:
ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
[assetsLib saveImage:imageToSave
toAlbum:#"AlbumName"
completion:completionBlock
failure:failureBlock];
You can use the ALAssetsLibrary for doing this:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library saveImage:image toAlbum:#"Midhun" withCompletionBlock:^(NSError *error) {
if (error!=nil) {
NSLog(#"Error: %#", [error description]);
}
}];
Check this tutorial also: Custom Photo Album
To the best of my knowledge Apple has not exposed an SDK to allow for this. After a review the UIKit function reference, My fear seems confirmed.