27

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

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

Nate
  • 31,017
  • 13
  • 83
  • 207
ios
  • 6,134
  • 20
  • 71
  • 103
  • 1
    +1 I seen it in many apps. http://stackoverflow.com/questions/15024361/add-image-on-lock-screen-in-ios-app-when-app-is-running-in-background – HDdeveloper Feb 22 '13 at 12:34

3 Answers3

39

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.

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
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.

Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207
  • 1
    Unfortunately this does not work on iOS 10 anymore. @Nate do you have info how to get this running on iOS 10? (For iOS 10 his code crashes with error: Assertion failed: (0), function SBSUIWallpaperClearVideo, file /BuildRoot/Library/Caches/com.apple.xbs/Sources/SpringBoardUIServices/SpringBoard-3563.15.8.9/SBSUIWallpaperUtilities.m, line 143.) Probably they added some smart asserts... ) – Guntis Treulands Mar 03 '17 at 15:57
  • 2
    @GuntisTreulands, yes I noticed that, too. I'm looking at [iOS 10 headers](https://github.com/nst/iOS-Runtime-Headers/blob/master/PrivateFrameworks/SpringBoardUIServices.framework/SBSUIWallpaperPreviewViewController.h) and it looks like the API is still there. Might be protected by entitlement, now. I do remember in the past finding other ways to do this, so let me spend some time this weekend trying other things to get this working. – Nate Mar 03 '17 at 22:14
  • @GuntisTreulands, I also tried using the similar method in `PLStaticWallpaperImageViewController`, but it also failed. It looks like iOS recognizes that the app is trying to change something outside its sandbox. I also see there's another API in [PhotoLibrary](https://github.com/nst/iOS-Runtime-Headers/blob/master/PrivateFrameworks/PhotoLibrary.framework/PLWallpaperImageViewController.h), but I have to do some reverse engineering to figure out what the parameter it takes is. I will keep you updated here. – Nate Mar 10 '17 at 05:52
1

use private api if you can check PLStaticWallpaperImageViewController

Bobo Shone
  • 721
  • 6
  • 16