How to set lock screen , wallpaper and Ringtone programmatically in iPhone?

In iPhone can we set the lock screen, wallpaper and ringtone programmatically?

If Yes, then please let me know how to set them?


Solution 1:

This can all be done easily, but will be rejected by Apple.

The ringtone can be changed by altering com.apple.SpringBoard.plist, specifically the ringtone key.

The following code can be used to read the actual ringtone title of custom ringtones (synced by iTunes).

NSMutableDictionary *custDict = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/private/var/mobile/Media/iTunes_Control/iTunes/Ringtones.plist"];
NSMutableDictionary *dictionary = [custDict objectForKey:@"Ringtones"];

NSArray *keys = [dictionary allKeys];
id key = [keys objectAtIndex:indexPath.row];
NSMutableDictionary *customRingtone = [dictionary objectForKey:key];
NSString *name = [customRingtone objectForKey:@"Name"];
cell.textLabel.text = name;

The Wallpapers can be overwritten at:

NSString *homePath1 = @"/private/var/mobile/Library/SpringBoard/HomeBackground.jpg";
NSString *homePath2 = @"/private/var/mobile/Library/SpringBoard/HomeBackgroundPortrait.jpg";
NSString *lockPath1 = @"/private/var/mobile/Library/SpringBoard/LockBackground.jpg";
NSString *lockPath2 = @"/private/var/mobile/Library/SpringBoard/LockBackgroundPortrait.jpg";

These examples were used in one of my Cydia apps. Theres not really much more to them, but these should get you going in the right direction.

Solution 2:

The answer by WrightsCS stopped working at some point due to a change in iOS. Unfortunately, this is something you have to live with if you wish to use undocumented features.

If you still need to do this, for non-App Store apps only, this code works in iOS 9.3. It could stop working in any future iOS release, though. (see comment below: no longer working in iOS 10)

#import "SBSUIWallpaperPreviewViewController.h"
#import <dlfcn.h>

// open the private framework dynamically
void *handle = dlopen("/System/Library/PrivateFrameworks/SpringBoardUIServices.framework/SpringBoardUIServices", RTLD_NOW);

UIImage *wallpaper = [UIImage imageNamed: @"background.jpg"];

Class sbClass = NSClassFromString(@"SBSUIWallpaperPreviewViewController");
// we create a view controller, but don't display it. 
//  just use it to load image and set wallpaper
SBSUIWallpaperPreviewViewController *controller = (SBSUIWallpaperPreviewViewController*)[[sbClass alloc] initWithImage: wallpaper];
[controller setWallpaperForLocations: 3];  // 3 -> set both for lock screen and home screen

dlclose(handle);

You'll need to add the private API header to your project. You can usually find these online with a little searching, for example, here.

In the example above, [SBSUIWallpaperPreviewViewController setWallpaperForLocations:] is called with an argument of 3: 3 indicates the image should be used for both lock and home screens. 1 indicates Lock screen only. 2 indicates Home screen only.


For an explanation of why I open this framework up dynamically, see my related answer here.

I don't have an answer regarding ringtones. This really should be a separate question: completely different APIs at work.