UnlimApps UnlimApps Official Blog

2Mar/120

Free Spotify on iPhone

In my attempt to listen to Spotify on my ps3 I discovered that I can pretty much get free Spotify on my iPhone using an iMac and a few tools.

First off you will need to get nicecast (http://rogueamoeba.com/nicecast/) which will allow you to publish the Spotify audio as a stream. Start up nicecast then choose spotify as the application you want to hook into and simply click broadcast. Then click on the share tab and you will find your local ip address something like http://192.168.1.5:8000/listen.m3u

Once you have nicecast you will need to make sure you can access your dekstop remotely outside your wireless network so get a http://www.no-ip.com/ account, get a free domain name to point to your desktop and download their tool to your desktop. Once thats done you will need to make sure to forward ports 8000 and 9877

After you have gotten all the above working, if you want to remotely control spotify you will need to get Remoteless from the app store and follow their instructions for setting up the remote app.

Lastly just visit the address http://192.168.1.5:8000/listen.m3u on mobile safari and it will play in the background and you can use the remoteless app to control the songs. There you go free mobile spotify access. If you are outside your local wireless network instead of 192.168.1.5 you will of course need to use your no-ip address to access spotify.

24Apr/111

UMBus For the UoM Magic Bus System

So I recently decided to take on the UoM Magic bus system and all the apps on the app store claiming to provide complete mobile access. One of the major differences between my app and those already on there is accurate live streaming of each stop's information as well as live tracking of the bus for each individual route so you can see where the bus is relative to the stop you are interested in just like the actual magic bus website located at http://mbus.pts.umich.edu/index.php

Also, I have added a map view for stops near to a person's location.

I have also added a favorites stops function which links to actual live tracking of a stop.

I will soon also add a trip planner. If you have any suggestions please add them in the comments

Below is a preview:

1Apr/113

Converting Audio (mp3 etc) files to m4a with AVAssetExportSession

Okay so I know many people ask for this and so I am going to give you the code for converting an audio file to an m4a on the iPhone with fade in. In order to use this you will need the core audio, core media, audio toolbox and avfoundation frameworks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
- (BOOL)exportAsset:(AVAsset *)avAsset toFilePath:(NSString *)filePath {
 
    // we need the audio asset to be at least 50 seconds long for this snippet
    CMTime assetTime = [avAsset duration];
    Float64 duration = CMTimeGetSeconds(assetTime);
    if (duration < 50.0) return NO;
 
    // get the first audio track
    NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeAudio];
    if ([tracks count] == 0) return NO;
 
    AVAssetTrack *track = [tracks objectAtIndex:0];
 
    // create the export session
    // no need for a retain here, the session will be retained by the
    // completion handler since it is referenced there
    AVAssetExportSession *exportSession = [AVAssetExportSession
                                           exportSessionWithAsset:avAsset
                                           presetName:AVAssetExportPresetAppleM4A];
    if (nil == exportSession) return NO;
 
    // create trim time range - 20 seconds starting from 30 seconds into the asset
    CMTime startTime = CMTimeMake(30, 1);
    CMTime stopTime = CMTimeMake(50, 1);
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
 
    // create fade in time range - 10 seconds starting at the beginning of trimmed asset
    CMTime startFadeInTime = startTime;
    CMTime endFadeInTime = CMTimeMake(40, 1);
    CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(startFadeInTime,
                                                            endFadeInTime);
 
    // setup audio mix
    AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix];
    AVMutableAudioMixInputParameters *exportAudioMixInputParameters =
            [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track];
 
    [exportAudioMixInputParameters setVolumeRampFromStartVolume:0.0 toEndVolume:1.0
                                   timeRange:fadeInTimeRange]; 
    exportAudioMix.inputParameters = [NSArray
                                      arrayWithObject:exportAudioMixInputParameters]; 
 
    // configure export session  output with all our parameters
    exportSession.outputURL = [NSURL fileURLWithPath:filePath]; // output path
    exportSession.outputFileType = AVFileTypeAppleM4A; // output file type
    exportSession.timeRange = exportTimeRange; // trim time range
    exportSession.audioMix = exportAudioMix; // fade in audio mix
 
    // perform the export
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
 
        if (AVAssetExportSessionStatusCompleted == exportSession.status) {
            NSLog(@"AVAssetExportSessionStatusCompleted");
        } else if (AVAssetExportSessionStatusFailed == exportSession.status) {
            // a failure may happen because of an event out of your control
            // for example, an interruption like a phone call comming in
            // make sure and handle this case appropriately
            NSLog(@"AVAssetExportSessionStatusFailed");
        } else {
            NSLog(@"Export Session Status: %d", exportSession.status);
        }
    }];
 
    return YES;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
- (BOOL)exportAsset:(NSString *)avAssetUrlString toFilePath:(NSString *)filePath {
 
    //First you need to declare an asset using its file url
    NSURL *url = [NSURL fileURLWithPath:avAssetUrlString];    
    AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
 
    // if you need the audio asset to be at least 50 seconds long or a diff value then uncomment this
 
    //CMTime assetTime = [avAsset duration];
    //Float64 duration = CMTimeGetSeconds(assetTime);
    //if (duration < 50.0) return NO;
 
    // get the first audio track
    NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeAudio];
    if ([tracks count] == 0) return NO;
 
    AVAssetTrack *track = [tracks objectAtIndex:0];
 
    // create the export session
    // no need for a retain here, the session will be retained by the
    // completion handler since it is referenced there
    AVAssetExportSession *exportSession = [AVAssetExportSession
                                           exportSessionWithAsset:avAsset
                                           presetName:AVAssetExportPresetAppleM4A];
    if (nil == exportSession) return NO;
 
    // create trim time range - 20 seconds starting from 30 seconds into the asset
    CMTime startTime = CMTimeMake(30, 1);
    CMTime stopTime = CMTimeMake(50, 1);
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
 
    // create fade in time range - 10 seconds starting at the beginning of trimmed asset
    CMTime startFadeInTime = startTime;
    CMTime endFadeInTime = CMTimeMake(40, 1);
    CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(startFadeInTime,
                                                            endFadeInTime);
 
    // setup audio mix
    AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix];
    AVMutableAudioMixInputParameters *exportAudioMixInputParameters =
            [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track];
 
    [exportAudioMixInputParameters setVolumeRampFromStartVolume:0.0 toEndVolume:1.0
                                   timeRange:fadeInTimeRange]; 
    exportAudioMix.inputParameters = [NSArray
                                      arrayWithObject:exportAudioMixInputParameters]; 
 
    // configure export session  output with all our parameters
    exportSession.outputURL = [NSURL fileURLWithPath:filePath]; // output path
    exportSession.outputFileType = AVFileTypeAppleM4A; // output file type
    exportSession.timeRange = exportTimeRange; // trim time range
    exportSession.audioMix = exportAudioMix; // fade in audio mix
 
    // perform the export
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
 
        if (AVAssetExportSessionStatusCompleted == exportSession.status) {
            NSLog(@"AVAssetExportSessionStatusCompleted");
        } else if (AVAssetExportSessionStatusFailed == exportSession.status) {
            // a failure may happen because of an event out of your control
            // for example, an interruption like a phone call comming in
            // make sure and handle this case appropriately
            NSLog(@"AVAssetExportSessionStatusFailed");
        } else {
            NSLog(@"Export Session Status: %d", exportSession.status);
        }
    }];
 
    return YES;
}

Enjoy!

Filed under: Server Admin 3 Comments
26Jan/110

Silence Now Alternative – Pickup2Silence

So I saw a tweak for sale called Silence Now and I really liked the concept but it didn't work for me and so I figured I would just make my own and I did. I have posted the source code for anyone interested in how this works below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#import <CaptainHook/CaptainHook.h>
#import <UIKit/UIKit.h>
#import <SpringBoard/SpringBoard.h>
 
CHDeclareClass(SBAccelerometerInterface);
CHDeclareClass(SBCallAlertDisplay);
 
static SBCallAlertDisplay *callAlert;
 
CHMethod(5, void, SBAccelerometerInterface, accelerometerDataReceived,double,received,x,float,x,y,float,y,z,float,z,type,unsigned,type)
{
if((x>0.3 || z> 0.1 || y>.1) && callAlert)
{
	[callAlert stopRingingOrVibrating];
	}
CHSuper(5, SBAccelerometerInterface, accelerometerDataReceived,received,x,x,y,y,z,z,type,type);
}
 
CHMethod(0, void, SBCallAlertDisplay, finishedAnimatingIn)
{
	if(!callAlert)
	{
	callAlert = [self retain];
	CHLoadLateClass(SBAccelerometerInterface);
	CHHook(5, SBAccelerometerInterface, accelerometerDataReceived,x,y,z,type);
	}
 
	CHSuper(0, SBCallAlertDisplay, finishedAnimatingIn);
}
 
CHMethod(0, void, SBCallAlertDisplay, answerAndRelease)
{
	CHSuper(0, SBCallAlertDisplay, answerAndRelease);
}
 
CHMethod(0, void, SBCallAlertDisplay, ignoreAndRelease)
{
	CHSuper(0, SBCallAlertDisplay, ignoreAndRelease);
}
 
CHConstructor
{
	CHLoadLateClass(SBCallAlertDisplay);
	CHHook(0, SBCallAlertDisplay, finishedAnimatingIn);
	CHHook(0, SBCallAlertDisplay, answerAndRelease);
	CHHook(0, SBCallAlertDisplay, ignoreAndRelease);
 
}

Filed under: Server Admin No Comments
3Dec/1060

Journey into Mobile Substrate

*Note this guide assumes you have version 3.0 of the iPhone SDK installed. If you have some other version simply run inside terminal:

sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk

Where 4.2 is your current sdk version

So in my attempt to learn more about iPhone programming I have come across this project:

https://github.com/rpetrich/theos

It is an open source framework by DHowett (for more info visit https://github.com/DHowett/theos) for compiling MobileSubstrate plugins - in this tutorial I am using the version by rpetrich b/c he includes the headers. There are a few guides out there on how to make MS plugins but they are not very clear and they require much reading (which in thinking back was all good for me so you should do the same).

With this tool in hand I am going to show you how to make your very first MS plugin.

First this is first you need to install theos. To do this do the following:

    1. Install git which can be done by first installing macports from http://www.macports.org/install.php
    2. Once macports are installed inside terminal run
    3. sudo port selfupdate
    4. then
    5. sudo port install git-core +svn
    6. Once git is installed run the following two commands inside terminal to install theos
    7. cd ~ && git clone git://github.com/rpetrich/theos.git
    8. now navigate to wherever you want to store your project and do the following:
    9. for example cd ~/Documents
    10. ~/theos/new-tweak.sh helloworld
    11. You will now have a folder in your documents directory named helloworld navigate inside to find
    12. tweak.m which look like so

 

  1. As you can see this is some very simple code
    • The "ClassName" is the class whose methods you want to overwrite
    • The  "someMethod" is the method of that class you want to overwrite
    • And the CHDeclareMethod is where you overwrite the method
    • So for this helloworld lets just display an alert when an application is launched/clicked
    • to do this we want to overwrite the method of SBApplicationIcon class
    • so in the tweak.m change ClassName to SBApplicationIcon
    • and someMethod to launch
    • Your tweak.m should now look like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#import <CaptainHook/CaptainHook.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIKit2.h>
#import <SpringBoard/SpringBoard.h>
 
CHDeclareClass(SBApplicationIcon);
 
CHMethod(0, void, SBApplicationIcon, launch)
{
	UIAlertView* __launchView = [[UIAlertView alloc] init];
	__launchView.title = @"Hello";
	__launchView.message = @"World";
	[__launchView addButtonWithTitle:@"Dismiss"];
	[__launchView show];
 
	//CHSuper(0, SBApplicationIcon, launch);
}
 
CHConstructor
{
	CHLoadLateClass(SBApplicationIcon);
	CHHook(0, SBApplicationIcon, launch);
}
    • And your makefile should look like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ifeq ($(shell [ -f ./framework/makefiles/common.mk ] && echo 1 || echo 0),0)
all clean package install::
	git submodule update --init
	./framework/git-submodule-recur.sh init
	$(MAKE) $(MAKEFLAGS) MAKELEVEL=0 $@
else
 
TWEAK_NAME = helloworld
helloworld_OBJC_FILES = Tweak.m
helloworld_FRAMEWORKS = UIKit
 
include framework/makefiles/common.mk
include framework/makefiles/tweak.mk
 
endif
  • Now you are almost done. in your terminal cd to the directory that contains your tweak.m and then just type make
  • This will place a file named helloworld.dylib in the obj directory.
  • Now you can ssh that file to /Library/MobileSubstrate/DynamicLibraries/
  • Then respring your device and you should now get an alert when you try to launch an app.

Hope that helps some people out. For more info make sure to read http://www.iphonedevwiki.net/index.php/MobileSubstrate and if you have any problems just leave a comment.

Eni9889

9Nov/105

UnlimTones+

Hi,

So I have decided to release a paid version of UnlimTones with no ads and a few extra features and I need beta testers. If you would like to beta test it please send me your UDID at [email protected]

Also, please report any errors/crashes in the comments of this post or send them to my email.

19Sep/1016

Download Manager

This post will show you how to make a very simple download/file manager for your iPhone application. I am not very good at memory management but I will do my best. Even so this should be a good starting point for anyone.

UPDATE:

I have rewritten the download manager and have archived all the classes you will need to include besides the ASIHTTP framework

Download Manger - NEW SOURCE

The Xcode Project

DownloadManager - OLD XCODE

The main classes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//
//  DlMan.h
//  UnlimVideosiPad
//
//  Created by Enea Gjoka on 5/4/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//
 
#import <UIKit/UIKit.h>
#import "ASIHTTPRequest.h"
#import <MediaPlayer/MediaPlayer.h>
 
@interface DlMan : UITableViewController <ASIHTTPRequestDelegate, UIActionSheetDelegate,UIAlertViewDelegate,UIDocumentInteractionControllerDelegate> {
 
	NSMutableArray *contentArray;
	NSMutableArray *progArray;
	NSString *saveTo;
	int Selected;
 
	//File Manager
	NSMutableArray *allFiles;
	int selectedRow;
	MPMoviePlayerController  *av;
	UITextField *myTextField;
 
}
 
@property (nonatomic, retain) NSMutableArray *contentArray;
@property (nonatomic, retain) NSMutableArray *progArray;
@property (nonatomic, retain) NSString *saveTo;
 
@property (nonatomic, retain) NSMutableArray *allFiles;
@property (nonatomic, retain) MPMoviePlayerController  *av;
@property (nonatomic, retain) UITextField *myTextField;
 
-(void)reloadMyData;
 
-(void)addDownload:(NSString *)theURL withName:(NSString *)fileName;
-(void)updateSaveToDL;
- (void)video:(NSString *) videoPath didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo;
@end
 
@interface MPMoviePlayerControllerInternalHack: NSObject
- (void)setTVOutEnabled:(BOOL)enabled;
- (void)displayVideoViewOnTV;
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
//
//  DlMan.m
//  UnlimVideosiPad
//
//  Created by Enea Gjoka on 5/4/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//
 
#import "DlMan.h"
#import "AppDelegate_iPhone.h"
#import "ASIHTTPRequest.h"
#import "PDColoredProgressView.h"
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
#import <QuickLook/QuickLook.h>
#endif
 
@implementation DlMan
 
@synthesize contentArray, progArray, saveTo, allFiles,av, myTextField;
 
/*
 - (id)initWithFrame:(CGRect)frame {
 if ((self = [super initWithFrame:frame])) {
 // Initialization code
 }
 return self;
 }
 */
 
- (id)initWithStyle:(UITableViewStyle)style {
	if (self = [super initWithStyle:style]) {
 
		self.navigationItem.rightBarButtonItem = self.editButtonItem;
		contentArray = [[NSMutableArray alloc] init];
		progArray = [[NSMutableArray alloc] init];
		self.view.backgroundColor = [UIColor clearColor];
		self.tabBarItem.image = [UIImage imageNamed:@"40-inbox.png"];
		self.tabBarItem.title = @"Transfers";
		AppDelegate_iPhone* delegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
		if([delegate saveTo] != nil)
		{
			saveTo = [delegate saveTo];
		}
 
		if(saveTo == nil)
		{
			saveTo = @"/var/mobile/Library/Downloads/";
		}
 
 
		allFiles = [[NSMutableArray alloc] init];
		NSDirectoryEnumerator *dirEnum = [ [ NSFileManager defaultManager ] enumeratorAtPath:saveTo];
		NSString *file;
		while ((file = [ dirEnum nextObject ])) 
		{
			if(file != nil)
			{
				if([file rangeOfString:@".mp4" options: NSCaseInsensitiveSearch].length > 0 || [file rangeOfString:@".mov" options: NSCaseInsensitiveSearch].length > 0 || [file rangeOfString:@".m4v" options: NSCaseInsensitiveSearch].length > 0 || [file rangeOfString:@".pdf" options: NSCaseInsensitiveSearch].length > 0 )
 
				{
					[ allFiles addObject: file];
				}
			}
		}
	}
	return self;
}
 
- (void)viewDidLoad {
    [super viewDidLoad];
	self.title = @"Downloads";
	// self.clearsSelectionOnViewWillAppear = NO;
 
}
 
//RootViewController.m
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
 
	if(section == 0)
		return @"Transfers";
	else
		return saveTo;
}
 
-(void)updateSaveToDL
{
	AppDelegate_iPhone* delegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
	if([delegate saveTo] != nil)
	{
		saveTo = [delegate saveTo];
	}
}
 
-(void)reloadMyData
{
	allFiles = [[NSMutableArray alloc] init];
	AppDelegate_iPhone* delegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
	if([delegate saveTo] != nil)
	{
		saveTo = [delegate saveTo];
	}
 
	NSDirectoryEnumerator *dirEnum = [ [ NSFileManager defaultManager ] enumeratorAtPath:saveTo];
	NSString *file;
	while ((file = [ dirEnum nextObject ])) 
	{
		if(file != nil)
		{
			if([file rangeOfString:@".mp4" options: NSCaseInsensitiveSearch].length > 0 || [file rangeOfString:@".mov" options: NSCaseInsensitiveSearch].length > 0 || [file rangeOfString:@".m4v" options: NSCaseInsensitiveSearch].length > 0 || [file rangeOfString:@".pdf" options: NSCaseInsensitiveSearch].length > 0)
			{
				[ allFiles addObject: file];
			}
		}
	}
 
 
}
 
-(void)addDownload:(NSString *)theURL withName:(NSString *)fileName
{
 
	BOOL isDir;
	NSFileManager *downloadsdir = [[NSFileManager alloc] init];
 
	if([downloadsdir fileExistsAtPath:saveTo isDirectory:&isDir] && isDir)
	{
		NSLog(@"The Dir Exists");
	}
	else{
		[downloadsdir createDirectoryAtPath:saveTo attributes:nil];
	}
 
	if([downloadsdir fileExistsAtPath:@"/var/mobile/Documents/Installous/Downloads/" isDirectory:&isDir] && isDir)
	{
		NSLog(@"The Dir Exists");
	}
	else{
		[downloadsdir createDirectoryAtPath:@"/var/mobile/Documents/Installous/Downloads/" attributes:nil];
	}
 
 
	[downloadsdir release];
	PDColoredProgressView *theProgress = [[PDColoredProgressView alloc] initWithFrame:CGRectMake(3, 17, 314, 14)];
	[theProgress setName:fileName];
	[theProgress setPl:@"Download Starting"];
 
	NSString *tmpExt;
	if([theURL rangeOfString:@"nextgenvidz.com" options:NSCaseInsensitiveSearch].length > 0)
	{
		tmpExt = @"_NGV";
	}
	else if([theURL rangeOfString:@"megaupload.com" options:NSCaseInsensitiveSearch].length > 0)
	{
 
		tmpExt = @"_Mega";
	}
	else if ([theURL rangeOfString:@"theogspot.com" options:NSCaseInsensitiveSearch].length > 0)
	{
		tmpExt = @"_theOG";
	}
	else {
		tmpExt = @"_etc";
	}
 
 
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:theURL]];
	[request setTemporaryFileDownloadPath:[@"/tmp/" stringByAppendingString:[fileName stringByAppendingString:tmpExt]]];
	[tmpExt release];
 
	if([fileName rangeOfString:@".ipa" options:NSCaseInsensitiveSearch].length > 0)
	{
		[request setDownloadDestinationPath:[@"/var/mobile/Documents/Installous/Downloads/" stringByAppendingString:fileName]];
	}
	else {
		[request setDownloadDestinationPath:[saveTo stringByAppendingString:fileName]];
	}
	[request setDelegate:self];
	[request setDownloadProgressDelegate:theProgress];
	request.allowResumeForFileDownloads = YES;
	[request startAsynchronous];
	[contentArray addObject:request];
	[progArray addObject:theProgress];
	[theProgress retain];
 
	[self.tableView reloadData];
 
	self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",[contentArray count]];
 
}
 
- (void)requestFinished:(ASIHTTPRequest *)request
{
	[self reloadMyData];
	[self.tableView reloadData];
}
 
- (void)requestFailed:(ASIHTTPRequest *)request
{
	//NSError *error = [request error];
	//NSLog([error localizedDescription]);
	NSLog(@"The download finished");
}
 
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
	[self.tableView reloadData];
}
 
- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	[self reloadMyData];
}
 
/*
 - (void)viewWillDisappear:(BOOL)animated {
 [super viewWillDisappear:animated];
 }
 */
/*
 - (void)viewDidDisappear:(BOOL)animated {
 [super viewDidDisappear:animated];
 }
 */
 
 
#pragma mark -
#pragma mark Table view data source
 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
    // Return the number of sections.
    return 2;
}
 
 
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    if(section == 0)
	{
		return [progArray count];
	}
	else {
		return [allFiles count];
	}
}
 
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    NSString *CellIdentifier = [NSString stringWithFormat:@"CellIdentifier_%i_%i",indexPath.section,indexPath.row];
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 
	cell = nil;
	if(indexPath.section == 0)
	{
		if (cell == nil) {
			cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
			cell.accessoryType = UITableViewCellAccessoryNone;
			cell.selectionStyle = UITableViewCellSelectionStyleNone;
		}
		[cell addSubview:[progArray objectAtIndex:indexPath.row]];
    }
	else {
		if (cell == nil) {
			cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
		}
		cell.selectionStyle = UITableViewCellSelectionStyleGray;
		cell.textLabel.text = [allFiles objectAtIndex:indexPath.row];
	}
 
	return cell;
}
 
 
/*
 // Override to support conditional editing of the table view.
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the specified item to be editable.
 return YES;
 }
 */
 
 
 
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 
	if(indexPath.section == 0)
	{
 
		if (editingStyle == UITableViewCellEditingStyleDelete) 
		{
			Selected = indexPath.row;
			//Remove The Temporary File
			NSFileManager *fileManager = [NSFileManager defaultManager];
			if([fileManager fileExistsAtPath:[(ASIHTTPRequest *)[contentArray objectAtIndex:indexPath.row] temporaryFileDownloadPath]])
			{
 
				UIActionSheet	*actionSheet = [[UIActionSheet alloc] initWithTitle:@"What do You Want to Do?...\n" 
																		 delegate:self 
																cancelButtonTitle:@"Save to Resume" 
														   destructiveButtonTitle:nil 
																otherButtonTitles:@"Delete It",nil];
				[actionSheet setActionSheetStyle:UIBarStyleBlackTranslucent];
				[actionSheet showInView:self.view];
				[actionSheet release];
 
			}
			else {
				[[contentArray objectAtIndex:Selected] cancel];
				[contentArray removeObjectAtIndex:Selected];
 
				int num = [[self.tabBarItem badgeValue] intValue];
				num = num - 1;
				if(num == 0)
				{
					self.tabBarItem.badgeValue = nil;
				}
				else {
					self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",num];	
				}
 
				[self.tableView reloadData];
 
			}
			[fileManager release];
			[progArray removeObjectAtIndex:Selected];
			[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
			[self.tableView reloadData];
		}
	}
	else {
		if (editingStyle == UITableViewCellEditingStyleDelete) {
			// Delete the row from the data source
			NSFileManager *fileManager = [NSFileManager defaultManager];
			[fileManager removeItemAtPath:[saveTo stringByAppendingString:[allFiles objectAtIndex:indexPath.row]] error:nil];
			[allFiles removeObjectAtIndex:indexPath.row];
			[fileManager release];
 
		}
 
		[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
		[tableView reloadData];
	}
 
 
}
 
 
#pragma mark -
#pragma mark Table view delegate
 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
	selectedRow = indexPath.row;
	if(indexPath.section == 1)
	{
		if([[allFiles objectAtIndex:(int)selectedRow] rangeOfString:@".pdf" options:NSCaseInsensitiveSearch].length > 0 || [[allFiles objectAtIndex:(int)selectedRow] rangeOfString:@".epub" options: NSCaseInsensitiveSearch].length > 0)
		{
			UIActionSheet *playSheet = [[UIActionSheet alloc] initWithTitle:@"Options" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Play on iPhone",nil];
			[playSheet setActionSheetStyle:UIBarStyleBlackTranslucent];
			[playSheet showInView:self.view];
			[playSheet release];
		}
		else {
			UIActionSheet *playSheet = [[UIActionSheet alloc] initWithTitle:@"Options" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Play on iPhone",@"Play on TV",@"Save to Photo Library",@"Rename",nil];
			[playSheet setActionSheetStyle:UIBarStyleBlackTranslucent];
			[playSheet showInView:self.view];
			[playSheet release];
		}
	}
 
}
 
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
	return self;
}
 
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
	return self.view;
}
 
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
	return self.view.frame;
}
 
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if ([actionSheet buttonTitleAtIndex:buttonIndex]== @"Play on iPhone")
	{
		if ([[UIApplication sharedApplication] respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
		{
 
		if([[allFiles objectAtIndex:(int)selectedRow] rangeOfString:@".pdf" options:NSCaseInsensitiveSearch].length > 0 || [[allFiles objectAtIndex:(int)selectedRow] rangeOfString:@".epub" options: NSCaseInsensitiveSearch].length > 0)
		{
			NSString *myString = [NSString stringWithFormat:@"%@",[allFiles objectAtIndex:(int)selectedRow]];
			UIDocumentInteractionController* docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:[saveTo stringByAppendingString:myString]]];
			docController.delegate = self;
			[docController presentPreviewAnimated:YES];
			[docController retain];
		}
		else {
 
		AppDelegate_iPhone* delegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
 
		NSString *myString = [NSString stringWithFormat:@"%@",[allFiles objectAtIndex:(int)selectedRow]];
 
		MPMoviePlayerViewController *theMovieView = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:[saveTo stringByAppendingString:myString]]];
		[theMovieView moviePlayer].movieSourceType = MPMovieSourceTypeFile;
		[theMovieView shouldAutorotateToInterfaceOrientation:YES];
		theMovieView.moviePlayer.useApplicationAudioSession = NO;
		[theMovieView moviePlayer].shouldAutoplay = TRUE;
		[[theMovieView moviePlayer].view setBackgroundColor:[UIColor blackColor]];
		[[theMovieView moviePlayer].backgroundView setBackgroundColor:[UIColor blackColor]];
		[[NSNotificationCenter defaultCenter] addObserver:[delegate tabBarController] selector:@selector(moviePlayBackDidFinish:) name:@"MPMoviePlayerPlaybackDidFinishNotification" object:theMovieView];			
		[[delegate myDownloadManager] presentMoviePlayerViewControllerAnimated:theMovieView ];
		}
		}
		else {
 
			av = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:[saveTo stringByAppendingString:[allFiles objectAtIndex:selectedRow]]]];	
			[av play];
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:@"MPMoviePlayerPlaybackDidFinishNotification" object:av];			
			id y = [av valueForKeyPath:@"_internal._videoViewController"];
			[y setTVOutEnabled:NO];
		}
 
 
	}
 
	if ([actionSheet buttonTitleAtIndex:buttonIndex]== @"Play on TV")
	{
		if ([[UIApplication sharedApplication] respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
		{
		AppDelegate_iPhone* delegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
 
		NSString *myString = [NSString stringWithFormat:@"%@",[allFiles objectAtIndex:(int)selectedRow]];
 
		MPMoviePlayerViewController *theMovieView = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:[saveTo stringByAppendingString:myString]]];
		[theMovieView moviePlayer].movieSourceType = MPMovieSourceTypeFile;
		[theMovieView shouldAutorotateToInterfaceOrientation:YES];
		theMovieView.moviePlayer.useApplicationAudioSession = NO;
		[theMovieView moviePlayer].shouldAutoplay = TRUE;
		[[theMovieView moviePlayer].view setBackgroundColor:[UIColor blackColor]];
		[[theMovieView moviePlayer].backgroundView setBackgroundColor:[UIColor blackColor]];
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:@"MPMoviePlayerPlaybackDidFinishNotification" object:[theMovieView moviePlayer]];			
		[[delegate tabBarController] presentMoviePlayerViewControllerAnimated:theMovieView ];
 
		id y = [[theMovieView moviePlayer] valueForKeyPath:@"_internal._implementation._videoViewController"];
		[y setTVOutEnabled:YES];
		[y displayVideoViewOnTV];
		}
		else {
			av = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:[saveTo stringByAppendingString:[allFiles objectAtIndex:selectedRow]]]];	
			[av play];
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:@"MPMoviePlayerPlaybackDidFinishNotification" object:av];			
			id y = [av valueForKeyPath:@"_internal._videoViewController"];
			[y setTVOutEnabled:YES];
			[y displayVideoViewOnTV];
		}
 
	}
 
	if ([actionSheet buttonTitleAtIndex:buttonIndex]== @"Rename")
	{
		UIAlertView *alert1 = [ [ UIAlertView alloc ] initWithTitle: @"Rename"
															message:@"Please Enter The New File Name\n Without an Extension\n\n"
														   delegate: self
												  cancelButtonTitle: @"Cancel"
												  otherButtonTitles: @"Save",nil];
		self.myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 93.0, 260.0, 25.0)];
		[self.myTextField setBackgroundColor:[UIColor whiteColor]];
		[alert1 addSubview:self.myTextField];	
		CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, 100.0);
		[alert1 setTransform:myTransform];
		[self.myTextField becomeFirstResponder];
		[alert1 show];
		[alert1 release];
	}
 
	if([actionSheet buttonTitleAtIndex:buttonIndex] == @"Delete It")
	{
		NSFileManager *fileManager = [NSFileManager defaultManager];
		[fileManager removeItemAtPath:[(ASIHTTPRequest *)[contentArray objectAtIndex:Selected] temporaryFileDownloadPath] error:nil];
		[fileManager release];
 
		[[contentArray objectAtIndex:Selected] cancel];
		[contentArray removeObjectAtIndex:Selected];
 
 
		int num = [[self.tabBarItem badgeValue] intValue];
		num = num - 1;
		if(num == 0)
		{
			self.tabBarItem.badgeValue = nil;
		}
		else {
			self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",num];	
		}
		[self.tableView reloadData];
	} 
	else if([actionSheet buttonTitleAtIndex:buttonIndex] == @"Save to Resume"){
		[[contentArray objectAtIndex:Selected] cancel];
		[contentArray removeObjectAtIndex:Selected];
 
		int num = [[self.tabBarItem badgeValue] intValue];
		num = num - 1;
		if(num == 0)
		{
			self.tabBarItem.badgeValue = nil;
		}
		else {
			self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",num];	
		}
 
		[self.tableView reloadData];
	}
	else if ([actionSheet buttonTitleAtIndex:buttonIndex] == @"Save to Photo Library")
	{
		NSString *tempPath = [NSString stringWithFormat:@"%@",[allFiles objectAtIndex:selectedRow]];
		tempPath = [saveTo stringByAppendingString:tempPath];		
		UISaveVideoAtPathToSavedPhotosAlbum(tempPath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
	}
 
}
 
- (void)video:(NSString *) videoPath didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo {
	NSLog(@"Finished saving video with error: %@", error);
}
 
 
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
 
	if(buttonIndex == actionSheet.cancelButtonIndex)
	{
 
		return;
 
	}
 
	if([actionSheet buttonTitleAtIndex:buttonIndex] == @"Save")
	{			
		NSString *textValue= self.myTextField.text;
        if(textValue==nil){
			return;
        } 
		else 
		{
			NSFileManager *fileManager = [[NSFileManager alloc] init];
			[fileManager moveItemAtPath:[saveTo stringByAppendingString:[allFiles objectAtIndex:selectedRow]] toPath:[saveTo stringByAppendingString:[textValue stringByAppendingString:@".mp4"]] error:nil];
			[allFiles replaceObjectAtIndex:selectedRow withObject:textValue];
			[fileManager setAttributes:[NSDictionary dictionaryWithObject:[NSNumber numberWithLong:0755] forKey:NSFilePosixPermissions] ofItemAtPath:[saveTo stringByAppendingString:[textValue stringByAppendingString:@".mp4"]] error:nil];
			[self reloadMyData];
			[self.tableView reloadData];
		}
    } 
 
 
}
 
 
-(void)moviePlayBackDidFinish:(NSNotification *) notification
{
	if ([[UIApplication sharedApplication] respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
	{
	MPMoviePlayerController *player = notification.object;
	[[NSNotificationCenter defaultCenter] removeObserver:self
													name:@"MPMoviePlayerPlaybackDidFinishNotification"
												  object:player];
	id y = [player valueForKeyPath:@"_internal._implementation._videoViewController"];
	[player stop];
	[y setTVOutEnabled:NO];
	[player autorelease];
	}
	else {
		MPMoviePlayerController *player = notification.object;
		[[NSNotificationCenter defaultCenter] removeObserver:self
														name:@"MPMoviePlayerPlaybackDidFinishNotification"
													  object:player];
		id y = [player valueForKeyPath:@"_internal._videoViewController"];
		[player stop];
		[y setTVOutEnabled:NO];
		[player autorelease];
	}
 
}
 
/*
 // Override to support rearranging the table view.
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
 }
 */
 
 
/*
 // Override to support conditional rearranging of the table view.
 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the item to be re-orderable.
 return YES;
 }
 */
 
 
#pragma mark -
#pragma mark Table view delegate
 
/*
 - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 
 
 // When a row is selected, set the detail view controller's detail item to the item associated with the selected row.
 
 //    detailViewController.detailItem = [NSString stringWithFormat:@"%@", [linksArray objectAtIndex:indexPath.row]];
 }
 */
 
#pragma mark -
#pragma mark Memory management
 
- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
 
    // Relinquish ownership any cached data, images, etc. that aren't in use.
}
 
- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}
 
 
- (void)dealloc {
	//    [detailViewController release];
	[contentArray release];
	[progArray release];
	[saveTo release];
    [super dealloc];
}
 
 
@end

11Sep/100

Hello Everyone

My name is Enea and I will be using this blog to write some tutorials on iPhone development. Specifically topics that others do not seem to want to cover or share like Download managers and file Managers which are really simple for experts but new iPhone-developers most likely find them very difficult.

I will try and have my first post by the end of next week.