Able to touch the background of activity indicator - iphone

In my iphone application an activity indicator is shown at the time of webservice call. My problem is that i am able to touch the view on which the activity indicator is shown.My view has textfields and buttons and i am able to enter values in the text fields and also change the button states while the activity indicator is still on it. Have anybody faced a similar situation? Does anybody know a solution to this problem? All helpful suggestions are welcomed.
Here is my activity indicator class.
ActivityProgressViewController.h
#import <UIKit/UIKit.h>
#interface ActivityProgressViewController : UIViewController {
IBOutlet UIActivityIndicatorView *_activityIndicator;
IBOutlet UILabel *_labelMessage;
NSString *_messageToShow;
}
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activityIndicator;
#property (nonatomic, retain) IBOutlet UILabel *labelMessage;
+ (ActivityProgressViewController*) createInstance;
- (void)show;
- (void)showWithMessage:(NSString*)message;
- (void)close;
+ (void)show;
+ (void)close;
#end
ActivityProgressViewController.m
#import "ActivityProgressViewController.h"
#define kACTIVITY_INDICATOR_NIB #"ActivityProgressViewController"
#implementation ActivityProgressViewController
#synthesize activityIndicator = _activityIndicator;
#synthesize labelMessage = _labelMessage;
static ActivityProgressViewController *_viewController;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad {
if (_messageToShow) _labelMessage.text = _messageToShow;
}
- (void)dealloc {
[_labelMessage release];
[_messageToShow release];
[_activityIndicator release];
[super dealloc];
}
+ (ActivityProgressViewController*) createInstance {
_viewController = [[ActivityProgressViewController alloc] initWithNibName:kACTIVITY_INDICATOR_NIB bundle:nil];
return _viewController;
}
- (void)show
{
[_activityIndicator startAnimating];
UIWindow *window = [[[UIApplication sharedApplication] windows]objectAtIndex:0];
NSLog(#"[[UIApplication sharedApplication] windows]===%#",[[UIApplication sharedApplication] windows]);
self.view.frame = CGRectMake(window.bounds.origin.x, window.bounds.origin.y, window.bounds.size.width, window.bounds.size.height);
[window addSubview:self.view];
}
- (void)showWithMessage:(NSString*)message {
_messageToShow = message;
[self show];
}
- (void)close
{
[self.view removeFromSuperview];
}
+ (void)show {
if (!_viewController) {
_viewController = [ActivityProgressViewController createInstance];
}
[_viewController show];
}
+ (void)close {
if (_viewController) {
[_viewController close];
}
}
#end
Here is how i call from my required class.
[ActivityProgressViewController show];
[ActivityProgressViewController close];
I also call the activity indicator while exporting audio.
This is the code I use for exporting
-(void)exportAudioFile:(AVComposition*)combinedComposition
{
[ActivityProgressViewController show];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:combinedComposition
presetName:AVAssetExportPresetPassthrough];
NSArray *presets =[AVAssetExportSession exportPresetsCompatibleWithAsset:combinedComposition];
NSLog(#"presets======%#",presets);
NSLog (#"can export: %#", exportSession.supportedFileTypes);
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
exportPath = [documentsDirectoryPath stringByAppendingPathComponent:#"CombinedNew.m4a"];
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = exportURL;
exportSession.outputFileType = #"com.apple.m4a-audio";
exportSession.shouldOptimizeForNetworkUse = YES;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (#"i is in your block, exportin. status is %d",
exportSession.status);
switch (exportSession.status)
{
case AVAssetExportSessionStatusFailed:
{
break;
}
case AVAssetExportSessionStatusCompleted:
{
exportSuccess = YES;
if (recorderFilePath)
{
NSError *finalurlError;
[[NSFileManager defaultManager]removeItemAtPath:recorderFilePath error:&finalurlError];
finalurlError = nil;
[[NSFileManager defaultManager]copyItemAtPath:[exportURL path] toPath:recorderFilePath error:&finalurlError];
NSLog(#"finalurlError 2-----%#",finalurlError);
}
[ActivityProgressViewController close];
fileUrl = [NSURL fileURLWithPath:recorderFilePath];
[self updatePlayerForUrl:fileUrl];
break;
}
case AVAssetExportSessionStatusUnknown:
{
break;
}
case AVAssetExportSessionStatusExporting:
{
break;
}
case AVAssetExportSessionStatusCancelled:
{
break;
}
case AVAssetExportSessionStatusWaiting:
{
break;
}
default:
{
NSLog (#"didn't get export status");
break;
}
};
}];
[exportSession release];
}

You're adding your activity indicator to the middle of another view, yes?
If so, you can do this in your show method:
self.superview.userInteractionEnabled = NO;
And in your close method:
self.superview.userInteractionEnabled = YES;
Here is where you'll find information on the UIView's userInteractionEnabled property: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instp/UIView/userInteractionEnabled
Hope this helps!

Related

iOS 9.3 Email with attachments never sends

Using the MFMailComposeViewController with attachments causes the email to stay in the Outbox and never get sent from my Air 2. Same app on my Pro with 9.2 sends fine.
//.h
#interface embEmailData : NSObject
{
NSArray *to;
NSArray *cc;
NSArray *bcc;
NSString *subject;
NSString *body;
NSArray *attachment;
}
#property (nonatomic, assign) BOOL optionsAlert;
-(void)setTo:(NSArray*)to;
-(NSArray*)to;
-(void)setCc:(NSArray*)cc;
-(NSArray*)cc;
-(void)setBcc:(NSArray*)bcc;
-(NSArray*)bcc;
-(void)setSubject:(NSString*)subject;
-(NSString*)subject;
-(void)setBody:(NSString*)body;
-(NSString*)body;
-(void)setAttachment:(NSArray*)attachment;
-(NSArray*)attachment;
-(void)setOptionsAlert:(BOOL)options;
//.m
#import "embEmailData.h"
#import <MessageUI/MFMailComposeViewController.h>
#import "UIImage+Utilities.h"
#import MessageUI;
#define kemailShowNSLogBOOL NO
#interface embEmailData () <MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate>
#property (nonatomic, strong) embEmailData *receivedData;
#property (nonatomic, strong) UIViewController *topVC;
#end
#implementation embEmailData
- (id)init {
self = [super init];
if (self) {
// Delay execution of my block for 0.1 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self postEmail];
});
_topVC = [UIApplication sharedApplication].keyWindow.rootViewController;
}
return self;
}
-(void)setTo:(NSArray*)_to
{
to = _to;
if (kemailShowNSLogBOOL) NSLog(#"%#",to);
}
-(NSArray*)to {
return to;
}
-(void)setCc:(NSArray*)_cc
{
cc = _cc;
if (kemailShowNSLogBOOL) NSLog(#"%#",cc);
}
-(NSArray*)cc {
return cc;
}
-(void)setBcc:(NSArray*)_bcc
{
bcc = _bcc;
if (kemailShowNSLogBOOL) NSLog(#"%#",bcc);
}
-(NSArray*)bcc {
return bcc;
}
-(void)setSubject:(NSString*)_subject
{
subject = _subject;
if (kemailShowNSLogBOOL) NSLog(#"%#",subject);
}
-(NSString*)subject {
return subject;
}
-(void)setBody:(NSString*)_body
{
body = _body;
if (kemailShowNSLogBOOL) NSLog(#"%#",body);
}
-(NSString*)body {
return body;
}
-(void)setAttachment:(NSArray*)_attachment
{
attachment = _attachment;
if (kemailShowNSLogBOOL) NSLog(#"%#",attachment);
}
-(NSArray*)attachment {
return attachment;
}
-(void)setOptionsAlert:(BOOL)options
{
if (options)
{
if (kemailShowNSLogBOOL) NSLog(#"options");
}
else
{
if (kemailShowNSLogBOOL) NSLog(#"no options");
}
_optionsAlert = options;
}
-(void)postEmail
{
_receivedData = self;
[self emailData];
}
#pragma mark - Email Delegates
-(void)emailData
{
if ([MFMailComposeViewController canSendMail] == YES) {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self; // <- very important step if you want feedbacks on what the user did with your email sheet
if(_receivedData.to)
[picker setToRecipients:_receivedData.to];
if(_receivedData.cc)
for (NSString *email in _receivedData.cc) {
NSLog(#"cc email: %#",email);
}
[picker setCcRecipients:_receivedData.cc];
if(_receivedData.bcc)
[picker setBccRecipients:_receivedData.bcc];
if(_receivedData.subject)
[picker setSubject:_receivedData.subject];
if(_receivedData.body)
[picker setMessageBody:_receivedData.body isHTML:NO]; // depends. Mostly YES, unless you want to send it as plain text (boring)
// attachment code
if(_receivedData.attachment) {
NSString *filePath;
NSString *justFileName;
NSData *myData;
UIImage *pngImage;
NSString *newname;
for (id file in _receivedData.attachment)
{
// check if it is a uiimage and handle
if ([file isKindOfClass:[UIImage class]]) {
NSLog(#"UIImage");
myData = UIImagePNGRepresentation(file);
[picker addAttachmentData:myData mimeType:#"image/png" fileName:#"image.png"];
// might be nsdata for pdf
} else if ([file isKindOfClass:[NSData class]]) {
NSLog(#"pdf");
myData = [NSData dataWithData:file];
NSString *mimeType;
mimeType = #"application/pdf";
newname = #"Westbrook Brochure.pdf";
[picker addAttachmentData:myData mimeType:mimeType fileName:newname];
// it must be another file type?
} else {
justFileName = [[file lastPathComponent] stringByDeletingPathExtension];
NSString *mimeType;
// Determine the MIME type
if ([[file pathExtension] isEqualToString:#"jpg"]) {
mimeType = #"image/jpeg";
} else if ([[file pathExtension] isEqualToString:#"png"]) {
mimeType = #"image/png";
pngImage = [UIImage imageNamed:file];
} else if ([[file pathExtension] isEqualToString:#"doc"]) {
mimeType = #"application/msword";
} else if ([[file pathExtension] isEqualToString:#"ppt"]) {
mimeType = #"application/vnd.ms-powerpoint";
} else if ([[file pathExtension] isEqualToString:#"html"]) {
mimeType = #"text/html";
} else if ([[file pathExtension] isEqualToString:#"pdf"]) {
mimeType = #"application/pdf";
} else if ([[file pathExtension] isEqualToString:#"com"]) {
mimeType = #"text/plain";
}
filePath= [[NSBundle mainBundle] pathForResource:justFileName ofType:[file pathExtension]];
NSLog(#"filePath %# ",filePath);
UIImage * thumb = [UIImage imageNamed:filePath];
UIImage * resizeThumb = [UIImage resizeImage:thumb withMaxDimension:999];
if ([[file pathExtension] isEqualToString:#"pdf"]) {
//myData = [NSData dataWithData:file];
myData = [[NSFileManager defaultManager] contentsAtPath:filePath];
NSLog(#"ITS A PDF");
} else // if it is anything but a png file
if (![[file pathExtension] isEqualToString:#"png"]) {
//myData = [NSData dataWithContentsOfFile:filePath];
myData = UIImageJPEGRepresentation(resizeThumb, 1.0);
} else {
myData = UIImagePNGRepresentation(resizeThumb);
}
newname = file;
[picker addAttachmentData:myData mimeType:mimeType fileName:newname];
}
}
}
picker.navigationBar.barStyle = UIBarStyleBlack; // choose your style, unfortunately, Translucent colors behave quirky.
[_topVC presentViewController:picker animated:YES completion:nil];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Status" message:[NSString stringWithFormat:#"Email needs to be configured before this device can send email. \n\n Use support#neoscape.com on a device capable of sending email."]
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultSaved:
break;
case MFMailComposeResultSent:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Thank you!" message:#"Email Sent Successfully"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
break;
case MFMailComposeResultFailed:
break;
default:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Status" message:#"Sending Failed - Unknown Error"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
break;
}
[_topVC dismissViewControllerAnimated:YES completion:nil];
}
-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
NSLog(#"FINISHED");
}
EDIT: It still sometimes randomly does this for me. They sit in Outbox until I delete them. I updated to 9.3.5 and the emails sent. Unsure of what is going on.
I went to delete my email account from my device (which is a corporate Gmail account). I noted that Mail, Calendar, Contacts and Notes were ON.
After deleting and adding in again Notes defaulted to OFF and my email can now send from my apps again. YMMV.

App doesn't save before going to background

I want to save some texts in textfields whenever the user goes to the background i think i wrote everything correctly since i followed many question/answers. However when I close my app my app doesn't save the text or even create a plist so when i reopen it, the textfields are empty. Here is the code:
RootViewController.h:
#interface RootViewController: UIViewController <UITextFieldDelegate> {
UITextField *textField1;
UITextField *textField2;
UITextField *textField3;
UITextField *textField4;
}
#property (nonatomic, retain) UITextField *textField1, *textField2, *textField3, *textField4;
#end
RootViewController.m:
#import "RootViewController.h"
#implementation RootViewController
#synthesize textField1, textField2, textField3, textField4;
...
- (UILabel*)addNewLabel:(NSString*)_text
{
//Initializing TextViews
}
....
- (NSString *) saveFilePathB
{
NSString *path = #"/Applications/AppDissassembler.app/Cache/savefileb.plist";
return path;
}
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
self.view.backgroundColor = [UIColor whiteColor];
//creating textfields
self.textField1 = [self addNewTextfield:60:80:175:true:#"Binary Name Here":1];
self.textField2 = [self addNewTextfield:60:145:200:true:#"Offset Here (0xOffset)":2];
self.textField3 = [self addNewTextfield:75:210:175:false:nil:3];
self.textField4 = [self addNewTextfield:75:310:175:false:nil:4];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSArray *values = [[NSArray alloc] initWithObjects:self.textField1.text,self.textField2.text,self.textField3.text,self.textField4.text,nil];
NSFileHandle *fout1;
[[NSFileManager defaultManager] createFileAtPath:[self saveFilePathB] contents:nil attributes:nil];
//open output file for writing
fout1 = [NSFileHandle fileHandleForWritingAtPath:[self saveFilePathB]];
[values writeToFile:[self saveFilePathB] atomically:YES];
[values release];
}
- (void)viewDidLoad
{
NSString *myPath = [self saveFilePathB];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists)
{
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
self.textField1.text = [values objectAtIndex:0];
self.textField2.text = [values objectAtIndex:1];
self.textField3.text = [values objectAtIndex:2];
self.textField4.text = [values objectAtIndex:3];
[values release];
}
UIApplication *myApp = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidEnterBackground:) name:#"UIApplicationDidEnterBackgroundNotification" object:myApp];
[super viewDidLoad];
}
- (void)dealloc {
[textField1 release];
[textField2 release];
[textField3 release];
[textField4 release];
[super dealloc];
}
#end
If I change this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidEnterBackground:) name:#"UIApplicationDidEnterBackgroundNotification" object:myApp];
to this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:myApp];
I get an error which says that UIApplicationDidEnterBackgroundNotification wasn't declared.
It wont run in method you try, so in UIApplicationDidEnterBackground delegate. All you have to do is handle your process while going into background with beginBackgroundTaskWithExpirationHandler. See this topic: topic
The second version you tried, where UIApplicationDidEnterBackgroundNotification is an identifier not a literal string, is the correct way to use this feature. It should be defined in UIApplication.h.
You say you are compiling on the iPhone itself, so it sounds like the development environment you have there is lacking this definition. I haven't tried that myself, so can't be sure.
Once you have got past the compilation error I would recommend to use NSLog to see where your code has got to, because this is easier than looking for the file to be created.

Opening a pdf inside the app breaks the design

I'm having some kind of problems with one thing, i'm making an app and i have a webview that shows a pdf file, and i have a button if clicked will call an UIDocumentInteractionController (open the pdf in a new window).
I will leave screenshots to make it easier:
When i open the app:
http://imgur.com/dpIEd
After i open the UIDocumentInteractionController:
http://imgur.com/VYV2N
Here's the code too
.h file
#interface pdfView : UIViewController <UIDocumentInteractionControllerDelegate>
{
IBOutlet UIActivityIndicatorView *loading;
IBOutlet UIWebView *Wview;
UIDocumentInteractionController *controller;
}
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *loading;
#property (nonatomic, retain) IBOutlet UIWebView *Wview;
#property (nonatomic, retain) UIDocumentInteractionController *controller;
-(void)buttonPressed;
-(IBAction)open_in:(id)sender;
-(IBAction)back:(id)sender;
#end
.m file
#import "pdfView.h"
#implementation pdfView
#synthesize loading,Wview;
#synthesize controller;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)viewDidLoad
{
[loading startAnimating];
[super viewDidLoad];
Wview.scalesPageToFit = TRUE;
Wview.multipleTouchEnabled = TRUE;
[Wview setOpaque:NO];
NSString *path = [[NSBundle mainBundle] pathForResource:#"guia_seguranca_2" ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[Wview loadRequest:request];
[loading stopAnimating];
}
-(IBAction)open_in:(id)sender
{
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"guia_seguranca_2" ofType:#"pdf"];
UIDocumentInteractionController* preview = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
preview.delegate = self;
[preview presentPreviewAnimated:YES];
[preview retain];
}
-(IBAction)back:(id)sender
{
[self.view removeFromSuperview];
}
-(void)buttonPressed
{
//[self.view removeFromSuperview];
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"guia_seguranca_2" ofType:#"pdf"];
UIDocumentInteractionController* preview = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
preview.delegate = self;
[preview presentPreviewAnimated:YES];
[preview retain];
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
[self.controller autorelease];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[super dealloc];
[Wview release];
[loading release];
}
#end
Thanks in advance.....
I would suggest not useing the webview and using a pdf app (ibook, cloudreader) like this.
//name of pdf
NSString * pathString = #"userguide";
//get pdf path
NSString * filePath = [[NSBundle mainBundle] pathForResource:pathString ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:filePath];
self.docController = [UIDocumentInteractionController interactionControllerWithURL:url];
BOOL isValid = [self.docController presentOpenInMenuFromRect:self.handBookLaunch.frame inView:self.view animated:YES];
if (!isValid) {
NSString * messageString = [NSString stringWithFormat:#"No PDF reader was found on your device. Please download a PDF reader (eg. iBooks)."];
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:messageString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
Solved, added this code for layout verification:
-(void) viewWillAppear:(BOOL)animated
{
CGRect arect=[[UIScreen mainScreen]applicationFrame];
CGRect anotherrect=[[UIApplication sharedApplication]statusBarFrame];
if(self.view.center.y==arect.size.height/2)
self.view.center=CGPointMake(self.view.center.x, self.view.center.y+anotherrect.size.height); // fix silliness in IB that makes view start 20 pixels higher than it should on iPhone
}
source: https://discussions.apple.com/thread/2658315?start=0&tstart=0

AlAssetsLibrary issue, code works in 4.3 but not 5.0

Here's my issue, if I access this class with iOS 4.X, the code works fine.... however whenever I try to access it with iOS 5.0, I get nil values for the groups & assets. What's the best way to get this to work? I'm posting the entire class for a reference...
.h
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "DejViewController.h"
#class Event, Venue;
#interface SelectMediaViewController : DejViewController <UITableViewDelegate, UITableViewDataSource> {
Event *event;
Venue *venue;
UITableView *tableView;
NSMutableArray *selectedAssets;
NSMutableArray *allMedia;
ALAssetsLibrary *library;
NSMutableArray *assetGroups;
}
#property (nonatomic, retain) Event *event;
#property (nonatomic, retain) Venue *venue;
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSMutableArray *allMedia;
#property (nonatomic, retain) NSMutableArray *assetGroups;
- (IBAction)continuePressed:(id)sender;
#end
.m
#import <ImageIO/ImageIO.h>
#import "SelectMediaViewController.h"
#import "CaptionAllMediaViewController.h"
#import "MediaItem.h"
#import "CLValueButton.h"
#import "SelectMediaTableViewCell.h"
#define kMediaGridSize 75
#define kMediaGridPadding 4
#define kSelectImageTag 828
#interface SelectMediaViewController(Private)
- (void)setContentForButton:(CLValueButton *)button withAsset:(ALAsset *)asset;
- (void)loadData;
#end
#implementation SelectMediaViewController
#synthesize event, venue;
#synthesize tableView;
#synthesize allMedia,assetGroups;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
selectedAssets = [[NSMutableArray alloc] init];
showNextButton = YES;
}
return self;
}
- (void)dealloc {
[tableView release];
[event release];
[venue release];
[library release];
[allMedia release];
[selectedAssets release];
[assetGroups release];
[super dealloc];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"SelectMediaViewController - viewDidLoad");
}
- (void)viewDidUnload {
NSLog(#"SelectMediaViewController - viewDidUnload");
[self setTableView:nil];
[super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(#"SelectMediaViewController - viewDidAppear");
[super viewDidAppear:animated];
[self setNavTitle:#"Select Media"];
[self loadData];
[self.tableView reloadData];
float contentOffset = self.tableView.contentSize.height - self.tableView.frame.size.height;
if (contentOffset < 0) contentOffset = 0;
[self.tableView setContentOffset:CGPointMake(0, contentOffset) animated:NO];
}
- (void)viewDidDisappear:(BOOL)animated {
NSLog(#"SelectMediaViewController - viewDidDisappear");
self.allMedia = nil;
[selectedAssets removeAllObjects];
[self.tableView reloadData];
}
- (void)loadData {
NSMutableArray *tempArray = [[NSMutableArray array] init];
library = [[ALAssetsLibrary alloc] init];
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
NSLog(#"See Asset: %#", result);
[tempArray addObject:result];
NSLog(#"assets count: %i", tempArray.count);
}
else {
NSLog(#"result nil or end of list");
}
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
NSLog(#"group: %#",group);
}
else {
NSLog(#"group nil or end of list");
}
if (stop) {
self.allMedia = [NSMutableArray arrayWithCapacity:[tempArray count]];
self.allMedia = tempArray;
NSLog(#"Loaded data: %d & %d", [tempArray count], [self.allMedia count]);
}
};
//ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {
}];
//[library release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)continuePressed:(id)sender {
if ([selectedAssets count] > 0) {
CaptionAllMediaViewController *captionVC = [[CaptionAllMediaViewController alloc] initWithNibName:nil bundle:nil];
captionVC.event = self.event;
captionVC.venue = self.venue;
// Create media items
NSMutableArray *mediaItems = [NSMutableArray arrayWithCapacity:[selectedAssets count]];
for (ALAsset *asset in selectedAssets) {
MediaItem *item = [[MediaItem alloc] init];
item.asset = asset;
NSDictionary *metadata = [[asset defaultRepresentation] metadata];
NSDictionary *gpsMeta = [metadata objectForKey:#"{GPS}"];
if (gpsMeta) {
float latitude = [[gpsMeta objectForKey:#"Latitude"] floatValue];
if ([[gpsMeta objectForKey:#"LatitudeRef"] isEqualToString:#"S"]) latitude = latitude * -1;
float longitude = [[gpsMeta objectForKey:#"Longitude"] floatValue];
if ([[gpsMeta objectForKey:#"LongitudeRef"] isEqualToString:#"W"]) longitude = longitude * -1;
item.location = CLLocationCoordinate2DMake(latitude, longitude);
}
[mediaItems addObject:item];
[item release];
}
captionVC.media = mediaItems;
[self.navigationController pushViewController:captionVC animated:YES];
[captionVC release];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Images Selected"
message:#"Please select at least one image to continue."
delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
}
- (void)imagePressed:(CLValueButton *)sender {
BOOL currentlySelected = [selectedAssets containsObject:sender.valueObject];
UIImageView *imageView = (UIImageView *)[sender viewWithTag:kSelectImageTag];
if (!currentlySelected) {
[imageView setImage:[UIImage imageNamed:#"image-select-active.png"]];
[selectedAssets addObject:sender.valueObject];
} else {
[imageView setImage:[UIImage imageNamed:#"image-select.png"]];
[selectedAssets removeObject:sender.valueObject];
}
}
#pragma Table view methods
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Getting table view count: %d", [self.allMedia count]);
if ([self.allMedia count] == 0) return 0;
return ceil([self.allMedia count] / 4.0);
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 83;
NSLog(#"return83");
}
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SelectMediaTableViewCell *cell = (SelectMediaTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:#"MEDIA_CELL"];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"SelectMediaTableViewCell" owner:nil options:nil] objectAtIndex:0];
// wire up selectors
[cell.image1 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image2 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image3 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image4 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
}
int startIndex = indexPath.row * 4;
for (int i = 0; i < 4; i++) {
ALAsset *thisAsset = (startIndex + i) < [self.allMedia count] ? [self.allMedia objectAtIndex:startIndex + i] : nil;
CLValueButton *button = nil;
switch (i) {
case 0:
button = cell.image1;
break;
case 1:
button = cell.image2;
break;
case 2:
button = cell.image3;
break;
case 3:
button = cell.image4;
break;
default:
break;
}
[self setContentForButton:button withAsset:thisAsset];
UIImageView *imageView = (UIImageView *)[button viewWithTag:kSelectImageTag];
// letse see if it's selected or not...
if ([selectedAssets containsObject:button.valueObject]) {
[imageView setImage:[UIImage imageNamed:#"image-select-active.png"]];
} else {
[imageView setImage:[UIImage imageNamed:#"image-select.png"]];
}
}
return cell;
}
- (void)setContentForButton:(CLValueButton *)button withAsset:(ALAsset *)asset {
button.hidden = asset == nil;
if (asset) {
CGImageRef image = [asset thumbnail];
[button setImage:[UIImage imageWithCGImage:image] forState:UIControlStateNormal];
}
[button setValueObject:asset];
}
#pragma -
#end
Any help would be much appreciated, I've been trying to figure this out for 3 days...
The ALAssetsLibrary page in the online documentation now says "The lifetimes of objects you get back from a library instance are tied to the lifetime of the library instance."

iOS 4 bluetooth discovery doesn't work

I'm reading "beginning iPad application development", and at the bluetooth chapter i'm testing the code exactly as it appears at the book. The only difference is that the book was for 3.2 and I'm using XCODE 4 for iOS >4.0.
XCODE does not throw any error or warning, it builds correctly, but when testing at the iPhone it doesn't discover other devices.
What's wrong?
The viewController.h looks like:
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
#interface pruebaBluetoothViewController : UIViewController
<GKSessionDelegate, GKPeerPickerControllerDelegate> {
GKSession *currentSession;
IBOutlet UITextField *txtMessage;
IBOutlet UIButton *connect;
IBOutlet UIButton *disconnect;
GKPeerPickerController *picker;
}
#property (nonatomic, retain) GKSession *currentSession;
#property (nonatomic, retain) UITextField *txtMessage;
#property (nonatomic, retain) UIButton *connect;
#property (nonatomic, retain) UIButton *disconnect;
-(IBAction) btnSend:(id) sender;
-(IBAction) btnConnect:(id) sender;
-(IBAction) btnDisconnect:(id) sender;
#end
While the .m looks like:
#import "pruebaBluetoothViewController.h"
#implementation pruebaBluetoothViewController
#synthesize currentSession;
#synthesize txtMessage;
#synthesize connect;
#synthesize disconnect;
- (void)viewDidLoad {
[connect setHidden:NO];
[disconnect setHidden:YES];
[super viewDidLoad];
}
-(IBAction) btnConnect:(id) sender {
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[connect setHidden:YES];
[disconnect setHidden:NO];
[picker show];
}
- (void)peerPickerController:(GKPeerPickerController *)pk
didConnectPeer:(NSString *)peerID
toSession:(GKSession *) session {
self.currentSession = session;
session.delegate = self;
[session setDataReceiveHandler:self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
picker.delegate = nil;
[picker autorelease];
[connect setHidden:NO];
[disconnect setHidden:YES];
}
-(IBAction) btnDisconnect:(id) sender {
[self.currentSession disconnectFromAllPeers];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
}
- (void)session:(GKSession *)session
peer:(NSString *)peerID
didChangeState:(GKPeerConnectionState)state {
switch (state) {
case GKPeerStateConnected:
NSLog(#"connected");
break;
case GKPeerStateDisconnected:
NSLog(#"disconnected");
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
break;
}
}
- (void)dealloc {
[txtMessage release];
[currentSession release];
[super dealloc];
}
- (void) mySendDataToPeers:(NSData *) data {
if (currentSession)
[self.currentSession sendDataToAllPeers:data
withDataMode:GKSendDataReliable
error:nil];
}
-(IBAction) btnSend:(id) sender {
//---convert an NSString object to NSData---
NSData* data;
NSString *str = [NSString stringWithString:txtMessage.text];
data = [str dataUsingEncoding: NSASCIIStringEncoding];
[self mySendDataToPeers:data];
}
- (void) receiveData:(NSData *)data
fromPeer:(NSString *)peer
inSession:(GKSession *)session
context:(void *)context {
//---convert the NSData to NSString---
NSString* str;
str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Data received"
message:str
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
looks like you missed the following Delegate Method:
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type {
GKSession *session = [[GKSession alloc] initWithSessionID:kTankSessionID displayName:nil sessionMode:GKSessionModePeer];
return [session autorelease]; // peer picker retains a reference, so autorelease ours so we don't leak.
}
Hope this helps.