Advertise Books Events Forum News Social Networking Support Us

sdkIQ for iPhone
($4.99)

Shape Up
($0.99)

Your First iPhone App
($1.99)

iVidCam Free
(free)

Kid Art
($0.99)

iPUBQUIZ
(£1.19)

ArtStudio
($3.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 07-04-2009, 03:31 AM   #1 (permalink)
Registered Member
 
Join Date: May 2009
Location: Singapore
Posts: 88
Default Is it possible to retrieve these information?

1) A list of apps that a user has installed on their device and app icons

or

2) A list of tunes on the device and then plays those tunes within the app

Anyone knows if these are possible?
__________________
Try out my latest game Piecehunters Lite for free

Else get the paid version for $1.99 cents and you can bring your progress from the lite version over to the premium version
gibtang is offline   Reply With Quote
Old 07-04-2009, 10:49 AM   #2 (permalink)
Tutorial Author
 
Join Date: Jun 2009
Posts: 25
Default

The first one is not possible; all applications are installed in their own sandbox, meaning that they cannot do anything outside their own application. This is true for all scenarios, but certain things are allowed by Apple, such as retrieving the users image folder etc. But I'm not sure if it works when it comes to music. I do not think Apple are keen to have compeditors when it comes to their iPod.

However, I'm not 100% sure about the first one, although it would surprise me a great deal if it was possible.
Bovn is offline   Reply With Quote
Old 07-04-2009, 12:49 PM   #3 (permalink)
Shmoopi Gaming
 
Shmoopi's Avatar
 
Join Date: Jun 2009
Posts: 181
Default

Quote:
Originally Posted by Bovn View Post
The first one is not possible; all applications are installed in their own sandbox, meaning that they cannot do anything outside their own application. This is true for all scenarios, but certain things are allowed by Apple, such as retrieving the users image folder etc. But I'm not sure if it works when it comes to music. I do not think Apple are keen to have compeditors when it comes to their iPod.

However, I'm not 100% sure about the first one, although it would surprise me a great deal if it was possible.
That's wrong, their is a way to check if an application is installed or not. Sometimes you may want to check if a specific app is installed on the device, in case you use custom URL schemes that require some other app to be installed (you could just gray out/disable some buttons then). Unfortunately, Apple apparently does not have any function that checks this for you, so I whipped one up. It does not enumerate every single app, instead it uses the MobileInstallation cache which is always up-to-date with SpringBoard and holds the Info dictionaries of all apps installed. Although you're not "supposed" to access the cache, it's readable my App Store apps. Here is my code which at least works perfectly fine with the Simulator:
Code:
// Declaration
BOOL APCheckIfAppInstalled(NSString *bundleIdentifier); // Bundle identifier (eg. com.apple.mobilesafari) used to track apps

// Implementation

BOOL APCheckIfAppInstalled(NSString *bundleIdentifier)
{
	static NSString *const cacheFileName = @"com.apple.mobile.installation.plist";
	NSString *relativeCachePath = [[@"Library" stringByAppendingPathComponent: @"Caches"] stringByAppendingPathComponent: cacheFileName];
	NSDictionary *cacheDict = nil;
	NSString *path = nil;
	// Loop through all possible paths the cache could be in
	for (short i = 0; 1; i++)
	{
	
		switch (i) {
	case 0: // Jailbroken apps will find the cache here; their home directory is /var/mobile
		path = [NSHomeDirectory() stringByAppendingPathComponent: relativeCachePath];
		break;
	case 1: // App Store apps and Simulator will find the cache here; home (/var/mobile/) is 2 directories above sandbox folder
		path = [[NSHomeDirectory() stringByAppendingPathComponent: @"../.."] stringByAppendingPathComponent: relativeCachePath];
		break;
	case 2: // If the app is anywhere else, default to hardcoded /var/mobile/
		path = [@"/var/mobile" stringByAppendingPathComponent: relativeCachePath];
		break;
	default: // Cache not found (loop not broken)
		return NO;
		break; }
		
		BOOL isDir = NO;
		if ([[NSFileManager defaultManager] fileExistsAtPath: path isDirectory: &isDir] && !isDir) // Ensure that file exists
			cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];
		
		if (cacheDict) // If cache is loaded, then break the loop. If the loop is not "broken," it will return NO later (default: case)
			break;
	}
	
	NSDictionary *system = [cacheDict objectForKey: @"System"]; // First check all system (jailbroken) apps
	if ([system objectForKey: bundleIdentifier]) return YES;
	NSDictionary *user = [cacheDict objectForKey: @"User"]; // Then all the user (App Store /var/mobile/Applications) apps
	if ([user objectForKey: bundleIdentifier]) return YES;
	
	// If nothing returned YES already, we'll return NO now
	return NO;
}
Here is an example of this, assuming that your app is named "yourselfmadeapp" and is an app in the app store.
Code:
NSArray *bundles2Check = [NSArray arrayWithObjects: @"com.apple.mobilesafari", @"com.yourcompany.yourselfmadeapp", @"com.blahblah.nonexistent", nil];
for (NSString *identifier in bundles2Check)
	if (APCheckIfAppInstalled(identifier))
		NSLog(@"App installed: %@", identifier);
	else
		NSLog(@"App not installed: %@", identifier);
Log Output:
Code:
2009-01-30 12:19:20.250 SomeApp[266:20b] App installed: com.apple.mobilesafari
2009-01-30 12:19:20.254 SomeApp[266:20b] App installed: com.yourcompany.yourselfmadeapp
2009-01-30 12:19:20.260 SomeApp[266:20b] App not installed: com.blahblah.nonexistent
Your welcome
Trackback for this code goes to:
Code Sample: Check if an app is installed - iDevKit
Shmoopi is offline   Reply With Quote
Old 07-04-2009, 01:56 PM   #4 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,560
Default

I'd be surprised if this works on non-jailbroken phones. I think SandboxTemplate.sb prevents you from reading "/private/var/mobile/Applications/" except for your own folder.

I'd test this on a device before relying on it.
__________________
smasher is offline   Reply With Quote
Old 07-04-2009, 02:03 PM   #5 (permalink)
Shmoopi Gaming
 
Shmoopi's Avatar
 
Join Date: Jun 2009
Posts: 181
Default

Quote:
Originally Posted by smasher View Post
I'd be surprised if this works on non-jailbroken phones. I think SandboxTemplate.sb prevents you from reading "/private/var/mobile/Applications/" except for your own folder.

I'd test this on a device before relying on it.
Thanks for the concern, but yes it does, their are several apps that already utilize this. One of the most popular being Skype. It uses this to detect if it is running on a jailbroken device. The sandboxtemplate does not prevent it from reading a local file outside of the sandbox, only writing to it, unless it's on a jailbroken phone.
Shmoopi is offline   Reply With Quote
Old 07-04-2009, 02:57 PM   #6 (permalink)
Registered Member
 
Join Date: May 2009
Location: Singapore
Posts: 88
Default

Quote:
Originally Posted by Shmoopi View Post
Thanks for the concern, but yes it does, their are several apps that already utilize this. One of the most popular being Skype. It uses this to detect if it is running on a jailbroken device. The sandboxtemplate does not prevent it from reading a local file outside of the sandbox, only writing to it, unless it's on a jailbroken phone.
Thanks Shmoopi, this is a surprise as I thought that the iPhone SDK would disallow access. But your code works only if I know the bundle identifier. But if I do not know it, there is no way I can find out the bundle identifier of any app that is already installed in the device?

Anyway, I went to the iPhone 3.0 OS SDK page at
iPod Library Access - Get Ready for iPhone OS 3.0 - iPhone Developer Program

and it mentions
For example, you could create a trivia game that uses the metadata of the user’s songs. Improve on an arcade game by using a playlist as its soundtrack, or add the ability to listen to podcast lectures in a note taking app. You can make almost any app more enjoyable by bringing a user’s personal music and audio choices into your app.
__________________
Try out my latest game Piecehunters Lite for free

Else get the paid version for $1.99 cents and you can bring your progress from the lite version over to the premium version
gibtang is offline   Reply With Quote
Old 07-04-2009, 06:55 PM   #7 (permalink)
Tutorial Author
 
Join Date: Jun 2009
Posts: 25
Default

Hm, I'm surprised

@gibtang; Sure you can. If you check the code you can see that you load a dictionary from the plist named "com.apple.mobile.installation.plist". This code is intended to check if any given application you require is installed and therefore included in that dictionary, but you could just as easily extract the entire plist from what I can see and, say, display it in a UITableView. Why not print it out with NSLog() so that you can see the contents of it?
Bovn is offline   Reply With Quote
Old 07-04-2009, 08:49 PM   #8 (permalink)
Shmoopi Gaming
 
Shmoopi's Avatar
 
Join Date: Jun 2009
Posts: 181
Default

Quote:
Originally Posted by Bovn View Post
Hm, I'm surprised

@gibtang; Sure you can. If you check the code you can see that you load a dictionary from the plist named "com.apple.mobile.installation.plist". This code is intended to check if any given application you require is installed and therefore included in that dictionary, but you could just as easily extract the entire plist from what I can see and, say, display it in a UITableView. Why not print it out with NSLog() so that you can see the contents of it?
Can you give an example of this?
Shmoopi is offline   Reply With Quote
Old 07-04-2009, 09:17 PM   #9 (permalink)
Registered Member
 
Join Date: May 2009
Location: Singapore
Posts: 88
Default

Quote:
Originally Posted by Bovn View Post
Hm, I'm surprised

@gibtang; Sure you can. If you check the code you can see that you load a dictionary from the plist named "com.apple.mobile.installation.plist". This code is intended to check if any given application you require is installed and therefore included in that dictionary, but you could just as easily extract the entire plist from what I can see and, say, display it in a UITableView. Why not print it out with NSLog() so that you can see the contents of it?
Hmm, ok. How about the app name itself? The one that appears below the icon?
__________________
Try out my latest game Piecehunters Lite for free

Else get the paid version for $1.99 cents and you can bring your progress from the lite version over to the premium version
gibtang is offline   Reply With Quote
Old 07-05-2009, 03:41 PM   #10 (permalink)
Tutorial Author
 
Join Date: Jun 2009
Posts: 25
Default

I didn't try this snippet myself, but I did yesterday when trying to create a simple method to demonstrate what I mentioned earlier about retrieving the entire application list. Yet the code didn't work for me at all using the Simulator 3.0. There was no error, but I didn't get a dictionary at all.

Does this really work for you guys?
But, basically what I meant earlier was that in the code a dictionary is created with the contents of the file that -- according to the developer who wrote it -- contains all the info.plist data of each and every one of the applications installed. So instead of looping through an array of application bundle indicators as you do in the example, you could just manipulate the dictionary directly and show it in a UITableView.

But I can't give you any code example since I couldn't make it work myself. Even without changing the code.
Bovn is offline   Reply With Quote
Old 07-10-2009, 01:24 PM   #11 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 7
Default

Yes, the code only seems to work on pre-3.0 (it does at least on 2.2.1). It seems Apple does enforce the sandbox rules a bit stricter than previously. Although you can still access /var/mobile/Applications and get a listing of all the application directories - but those are in "08A9EF7A-8E49-4098-90F9-675CFC59208F" form. So unless somebodies knows how to get an appID out of this it's pretty useless.
martinr_vienna is offline   Reply With Quote
Old 09-04-2009, 11:05 PM   #12 (permalink)
Registered Member
 
rayhklee's Avatar
 
Join Date: Oct 2008
Location: Hong Kong
Posts: 22
Default

I am using the code provided, but I found that CacheDict : (null), there is no com.apple.mobile.installation.plist in the simulator
rayhklee is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Enter the iPhone App Challenge!  Win $500!
» Advertisements
» Stats
Members: 23,994
Threads: 38,776
Posts: 170,152
Top Poster: smasher (2,560)
Welcome to our newest member, wionj
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 09:55 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0