Media picker item selection - ios

i want my code to allow me to pick multiple items via my ipod library. Currently I am able to select one song. i want to modify my code to allow for a series of songs to be added to the que. Currently selecting YES for "pick multiple items" allows for selection however playback consists of only one song. the first selected.
How may I change this. I have included a sample of my code below...
#implementation ProjectViewController
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[self performSelector:#selector(presentLibrary) withObject:nil afterDelay:0.1];
[super viewDidLoad];
}
-(void)presentLibrary
{
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];
// picker.navigationController.delegate = self;
picker.delegate = self;
picker.allowsPickingMultipleItems = YES;
picker.prompt = NSLocalizedString (#"Select any song from the list", #"Prompt to user to choose some songs to play");
//[self.view addSubview:picker.view];
[self presentModalViewController: picker animated: YES];
//picker.view.frame = CGRectMake(picker.view.frame.origin.x, 0, picker.view.frame.size.width, picker.view.frame.size.height);
[picker release];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (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 {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
//return (interfaceOrientation == UIInterfaceOrientationPortrait);
return YES;
}
- (void)dealloc {
[super dealloc];
}
- (IBAction)onlaunch:(id)sender
{
xxxxxxxx ViewController *viewController = [[xxxxxxxxxViewController alloc] init];
[self presentModalViewController:viewController animated:YES];
[viewController release];
}
-(void)viewDidAppear:(BOOL)animated
{
}
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection
{
[self dismissModalViewControllerAnimated: NO];
//[mediaPicker.view removeFromSuperview];
//NSURL *url = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"screen1.mp4"]]; //test.caf
NSURL *url = [[mediaItemCollection.items objectAtIndex: 0] valueForProperty:MPMediaItemPropertyAssetURL];
NSLog(#"url:%#",url);
[[ShareInfo shareduserInfoManager] setSongUrl:url];
[self goToxxxxxxxxxyView];
}
- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker
{
[self dismissModalViewControllerAnimated: NO];
[[ShareInfo shareduserInfoManager] setSongUrl:nil];
[self goToxxxxxxxxxView];
}
-(void)goToxxxxxxxView
{
xxxxxxxxxxxxxx *viewController = [[xxxxxxxxxxxxxxxr alloc] init];
[self presentModalViewController:viewController animated:YES];
[viewController release];
}
#end

Instead of
NSURL *url = [[mediaItemCollection.items objectAtIndex: 0] valueForProperty:MPMediaItemPropertyAssetURL];
Which is selecting the 1st song,
try
if (mediaItemCollection)
[musicPlayer setQueueWithItemCollection: mediaItemCollection];

Related

ViewdidAppear fires for the second VC before the first

2015-02-06 23:23:35.976 a[47551:2124298] second view did load
2015-02-06 23:23:35.978 a[47551:2124298] first view did load
2015-02-06 23:23:36.060 a[47551:2124298] second view did appear
2015-02-06 23:23:36.062 a[47551:2124298] first view did appear
The above describes my problem. I want to do stuff only after the second view appears, but all the events first as soon as I launch the app.
The first view:
#interface AddViewController ()
#end
#implementation AddViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"first view did load");
// Do any additional setup after loading the view.
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"first view did appear");
}
- (IBAction)addBtnPressed:(id)sender {
NSLog(#"add Btn pressed");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
ViewController *destVC = [segue destinationViewController];
destVC.destStation = self.destField.text;
}
The second view:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"second view did load");
manager = [[ CLLocationManager alloc] init];
geocoder = [[ CLGeocoder alloc] init];
[manager requestWhenInUseAuthorization];
// [manager requestAlwaysAuthorization];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"second view did appear");
manager.delegate = self;
manager.desiredAccuracy = kCLLocationAccuracyBest;
NSLog(#"setting destStation %#", self.destStation);
self.destField.text = self.destStation;
self.destStationLoc = [LocationCalc findDestStationLoc:self.destStation stationInfos:[StationDB database].stationInfos];
}
The segue is connected from the button from the first VC.
Am I doing something wrong?

how to present the same view controller after dismissing its once in iOS

In my app I have a UITabBarController which has four view controllers. In every view controller I have a collection view. In each collection view I have some images. When I select an image from the third view controller it opens a web view controller which is not in UITabBarController.
In web view controller I have a back button on top with navigation bar. After pressing that back button it's coming back to third view controller. Again when I select another image in third view controller, it should open the web view controller, but the web view controller didn't appear on simulator instead saying error 1thread,1breakpoint.
Here is my code:
This code is in thirdviewcontroller after selecting the image
webViewController = [[AppsWebViewController alloc]init];
[self presentViewController:webViewController animated:YES completion:nil];
This code is in webviewcontroller after pressing the back button
[self dismissViewControllerAnimated:YES completion:nil];
I need the webviewcontroller to open every time after selecting any image in any of the four view controllers.
my thirdviewcontroller code:
#import "FreqAppsThirdViewController.h"
#interface FreqAppsThirdViewController ()
#end
#implementation FreqAppsThirdViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
icons = [NSArray arrayWithObjects:#"amazon-1.png",#"best_buy.png",#"Carl-Icahn-Lectures-Apple-Gambles-Netflix-and-Threatens-eBay-2.jpg",#"index.jpg",#"Office-Max.jpg", nil];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
_collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[_collectionView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:_collectionView];
[super viewDidLoad];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return icons.count;
}
// The cell that is returned must be retrieved from a call to - dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:[icons objectAtIndex:indexPath.row]]];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionViewdidSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
NSURL *url = [NSURL URLWithString:#"http://www.amazon.com/"];
webViewController = [[FreqAppsWebViewController alloc]initWithURL:url andTitle:#"Amazon"];
[self presentViewController:webViewController animated:YES completion:nil];
} else if (indexPath.row == 1){
NSURL *url = [NSURL URLWithString:#"http://www.bestbuy.com/"];
webViewController = [[FreqAppsWebViewController alloc]initWithURL:url andTitle:#"Best Buy"];
[self presentViewController:webViewController animated:YES completion:nil];
} else if (indexPath.row == 2){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.ebay.com"]];
} else if (indexPath.row == 3){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.walmart.com"]];
} else if (indexPath.row == 4){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.officemax.com"]];
}
// datasetCell.backgroundColor = [UIColor blueColor]; // highlight selection
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(50, 50);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout(UICollectionViewLayout*)collectionViewLayoutinsetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(50, 20, 50, 20);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
my webviewcontroller code:
#import "FreqAppsWebViewController.h"
#import "FreqAppsThirdViewController.h"
#import "FreqAppsAppDelegate.h"
#interface FreqAppsWebViewController ()
#end
#implementation FreqAppsWebViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)string {
if( self = [super init] ) {
theURL = url;
theTitle = string;
}
return self;
}
-(id)initWithURL:(NSURL *)url {
return [self initWithURL:url andTitle:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
webTitle.title = theTitle;
NSURLRequest *requestObject = [NSURLRequest requestWithURL:theURL];
[webView loadRequest:requestObject];
}
- (IBAction) back:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
webView.delegate = nil;
[webView stopLoading];
}
#end
my webviewcontroller.h code
#import <UIKit/UIKit.h>
#interface FreqAppsWebViewController : UIViewController <UIWebViewDelegate>
{
NSURL *theURL;
NSString *theTitle;
IBOutlet UIWebView *webView;
IBOutlet UINavigationItem *webTitle;
}
- (id)initWithURL:(NSURL *)url;
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)string;
- (IBAction)back:(id)sender;
#end
my thirdviewcontroller.h code:
#import <UIKit/UIKit.h>
#import "FreqAppsWebViewController.h"
#interface FreqAppsThirdViewController:UIViewController<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
{
UICollectionView *_collectionView;
NSArray *icons;
FreqAppsWebViewController *webViewController;
}
#end
Copy and paste the full error message you're getting.
If it is a breakpoint, not an error, as you seem to be indicating, it might just be that you clicked on a the margin of your source and set a breakpoint without realizing it.
To check for breakpoints:
Press Command 7 to display the breakpoint navigator and see if there are any breakpoints set in your code. If there are, you'll an outline starting with the target (the current app) then the source file .m, and then an entry listing a method name and line number, with a symbol that looks like a cross between a right-pointing arrow and a blue sticky note.
If there are breakpoints, select them one at a time and note where they are in your code. Are then in your IBAction method, or the one of the methods in your AppsWebViewController?
Delete each breakpoint by selecting it and pressing the delete key. Then run your program again.

Autolayout IOS 7 Storyboard Force Landscape or Portrait

I have a single storyboard where a majority of the views should be in portrait mode but one should be in Landscape. I've down a significant amount of searching but keep coming up a little blank.
My current implementation which isn't exactly seeming to work as I hoped consists of the following bits of code I've pieced together from this website:
I've made a RotationalViewController which extends from UINavigationController
#import "RotationControlledViewController.h"
#interface RotationControlledViewController ()
#end
#implementation RotationControlledViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation ret = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
return ret;
}
#end
And then I've made a PortraitViewController
#import "PortraitViewController.h"
#interface PortraitViewController ()
#end
#implementation PortraitViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
and a LandscapeViewController
#import "LandscapeViewController.h"
#interface LandscapeViewController ()
#end
#implementation LandscapeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
#end
I have played around with changing some of the settings but to no avail. My general plan of attack has been to make specific view controllers inherit from either LandscapeViewController or PortraitViewController if I want to lock them to a specific orientation.
Things seem to be working for portrait view ( i can lock controllers into portrait view) but I seem unable to load my 1 landscape view and have it a) auto rotate to landscape upon load, or b) rotate to landscape at all.
Any suggestions would be very appreciated.
Applying the solution presented in:
Force controllers to Change their orientation in Either Portrait or Landscape
I was able to make things work.
In both my PortraiteViewController and LandscapeViewControllers I modified the viewDidLoad method to:
PortraiteViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
LandscapeViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
This solution MAY stop working after IOS7 because both presentModalViewController and dismissModalViewController are deprecated.

Can't hide HUD in UIWebView for IOS project

I have a UIWebView that uses a ATM HUD while the web page is loading. I can get the HUD to start working, but after the web page loads, it stays there. I need to find a way to get the HUD to stop spinning once loaded. Below is the code I have so far..
#implementation ThenewsViewController
#synthesize hud;
- (void)showHud {
// Show hud with activity indicator
NSLog(#"hud: %#", hud);
if (!hud) {
hud = [[ATMHud alloc] initWithDelegate:self];
[self.navigationController.view addSubview:hud.view];
[hud setCaption:#"Loading news..."];
[hud setActivity:YES];
[hud update];
if (![hud isBeingPresented])
[hud show];
} else {
NSLog(#"hud exists... resetting.");
hud = nil;
[self showHud];
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *myURL = [NSURL URLWithString:#"http://www.hiphopdx.com/m/index.php?s=news"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myURL];
[myWebView loadRequest:myRequest];
UIColor *navBarColor = UIColorFromRGB(0x089932);
[[self.navigationController navigationBar] setTintColor:navBarColor];
if (![hud isBeingPresented])
[self showHud];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"Done loading web view");
[hud hide];
}
#end
How about this?
ATMHud *blargh;
if(loaded)
{
blargh.hidden = YES;
}
Try this:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// stop animating here
}
also
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// stop animating here also
}
Also make sure your "myWebView" instance delegate is set.
F.e _myWebView.delegate = self;

Switching to Another View, IOS

I am new to the coding world but am working on an app. I have code set up so that a password is required but then I want it to go into my next view which is to take a picture. I'm sorry if this is a stupid question but I need help.
TestViewController.m file
#import "TestViewController.h"
#interface TestViewController ()
#end
#implementation TestViewController
- (IBAction)enterpassword
{
NSString *passwordString = [NSString stringWithFormat:#"1234"];
if ([passwordfield.text isEqualToString:passwordString]) {
// Password is correct
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Correct Password" message:#"Password is Correct." delegate:self cancelButtonTitle:#"Enter" otherButtonTitles:nil];
[alert show];
[alert release];
}
else {
// Password is incorrect
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Incorrect Password" message:#"Password is Incorrect." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[actionSeat release];
[super dealloc];
}
#end
#implementation PhotoAppViewController
#synthesize imageView,choosePhotoBtn, takePhotoBtn;
-(IBAction) getPhoto:(id) sender {
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if((UIButton *) sender == choosePhotoBtn) {
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
} else {
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
imageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (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 {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
you need to create your view controller, then push it on, or you could present it modally.
like this:
if ([passwordfield.text isEqualToString:passwordString]) {
// Password is correct
PhotoAppViewController *viewController = [[[PhotoAppViewController alloc] init] autorelease];
[self pushViewController:PhotoAppViewController animated:YES];
}
else {
// Password is incorrect
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Incorrect Password" message:#"Password is Incorrect." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
You don't really need to put up an alert saying the password was correct... just have it work.

Resources