Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-5436] iOS: Expose SystemAlert

GitHub Issuen/a
TypeNew Feature
PriorityLow
StatusClosed
ResolutionFixed
Resolution Date2016-10-31T16:16:15.000+0000
Affected Version/sRelease 1.8.0
Fix Version/sRelease 6.1.0
ComponentsiOS
Labelsqe-6.1.0
ReporterDawson Toth
AssigneeHans Knöchel
Created2011-10-05T02:03:15.000+0000
Updated2016-11-17T17:58:56.000+0000

Description

Feature

Not all sounds that an app plays are media, so we should expose the SystemAlert through the Media module. This will let developers choose the most appropriate way to play a sound.

Example Usage

var systemAlert = Ti.Media.createSystemAlert({
    url: 'bad.wav'
});

for (var i = 0; i < 10; i++) {
    systemAlert.play();
    var until = new Date().getTime() + 300;
    while (until > new Date().getTime()) {}
}

Example Implementation

#import "TiProxy.h"
#import "TiUtils.h"
#import <AudioToolbox/AudioServices.h>

@interface TiMediaSystemAlertProxy : TiProxy {
    NSURL* url;
    TiFile *tempFile;
    SystemSoundID sound;
}
    
@property (nonatomic,readonly) NSURL *url;

-(void)play:(id)args;

@end
#import "TiMediaSystemAlertProxy.h"

@implementation TiMediaSystemAlertProxy

#pragma mark Proxy Lifecycle

-(id)init
{
    return [super init];
}

-(void)_destroy
{
    if (sound) {
        AudioServicesDisposeSystemSoundID(sound);
    }
    RELEASE_TO_NIL(url);
    [super _destroy];
}

#pragma mark System Sound

-(NSURL*)url
{
    return url;
}
-(void)setUrl:(id)url_
{
    RELEASE_TO_NIL(url);
    
    if ([url_ isKindOfClass:[NSString class]])
    {
        url = [[TiUtils toURL:url_ proxy:self] retain];
        
        if ([url isFileURL]==NO)
        {
            // we need to download it and save it off into temp file
            NSData *data = [NSData dataWithContentsOfURL:url];
            NSString *ext = [[[url path] lastPathComponent] pathExtension];
            tempFile = [[TiFile createTempFile:ext] retain]; // file auto-deleted on release
            [data writeToFile:[tempFile path] atomically:YES];
            RELEASE_TO_NIL(url);
            url = [[NSURL fileURLWithPath:[tempFile path]] retain];
        }
    }
    else if ([url_ isKindOfClass:[TiBlob class]])
    {
        TiBlob *blob = (TiBlob*)url_;
        //TODO: for now we're only supporting File-type blobs
        if ([blob type]==TiBlobTypeFile)
        {
            url = [[NSURL fileURLWithPath:[blob path]] retain];
        }
    }
    else if ([url_ isKindOfClass:[TiFile class]])
    {
        url = [[NSURL fileURLWithPath:[(TiFile*)url_ path]] retain];
    }
    
    if (sound) {
        AudioServicesDisposeSystemSoundID(sound);
    }
    AudioServicesCreateSystemSoundID((CFURLRef)url, &sound);
}

-(void)play:(id)args
{
    if (url == nil)
        return;
    AudioServicesPlayAlertSound(sound);
}

@end

Android Implementation

I'm not sure what the corresponding feature on Android would be.

Comments

  1. Flavio De Stefano 2016-09-19

    https://github.com/appcelerator/titanium_mobile/pull/8396
  2. Hans Knöchel 2016-10-31

    Test-case for QE:
       var systemAlert = Ti.Media.createSystemAlert({
           url: 'test.wav'
       });
        
       var win = Ti.UI.createWindow({
           backgroundColor: "#fff"
       });
       
       var btn = Ti.UI.createButton({
           title: "Play 10 sounds"
       });
       
       btn.addEventListener("click", function() {
       	for (var i = 0; i < 10; i++) {
       	    systemAlert.play();
       	    var until = new Date().getTime() + 300;
       	    while (until > new Date().getTime()) {}
       	}
       });
       
       win.add(btn);
       win.open();
       
  3. Harry Bryant 2016-11-17

    Verified as fixed, SystemAlert is now supported on iOS9 & iOS10. Tested On: iPhone 6 Plus 10.1.1 Device & Simulator iPhone 5S 9.3.5 Device Mac OS Sierra (10.12.1) Ti SDK: 6.1.0.v20161116071014 Appc Studio: 4.8.0.201611121409 Appc NPM: 4.2.8 App CLI: 6.1.0-14 Xcode 8.1 Node v4.4.7 *Closing ticket.*

JSON Source