I need to get the full length of an album that is on a device but don't get the correct result. What I have is the follwing to get an Array with the songs of one album:
MPMediaPropertyPredicate *albumNamePredicate = [MPMediaPropertyPredicate predicateWithValue:albumTitle
forProperty: MPMediaItemPropertyAlbumTitle];
MPMediaQuery *myAlbumQuery = [[MPMediaQuery alloc] init];
[myAlbumQuery addFilterPredicate: albumNamePredicate];
songsAlbumList = [myAlbumQuery items];
To get the length of a song, I use this:
NSNumber *songTrackLength = [song valueForProperty:MPMediaItemPropertyPlaybackDuration];
int minutes = floor([songTrackLength floatValue] / 60);
int seconds = trunc([songTrackLength floatValue] - minutes * 60);
TracklengthLabel.text = [NSString stringWithFormat:#"%d:%02d", minutes, seconds];
So the above works fine, I just do not get a correct addition of the songdurations ... Any ideas?
So I solved it - my problem was that I did not know how to correctly do the math with NSNumbers - I did not know that I was looking for that, that's why I did not ask for it. Here is the code I came up with to calculate the length of an album on you device:
- (void)fullAlbumLength
{
for (int i=0; i < songsAlbumList.count; i++)
{
if (addLength == NULL) // addLength and addLengthNew are NSNumber variables
{
addLength = [[self.albumTracksList objectAtIndex:i] valueForProperty: #"playbackDuration"];
}
else
{
addLengthNew = [[self.albumTracksList objectAtIndex:i] valueForProperty: #"playbackDuration"];
addLength = [NSNumber numberWithFloat:([addLength floatValue] + [addLengthNew floatValue])];
}
}
fullminutes = floor([addLength floatValue] / 60); // fullminutes is an int
fullseconds = trunc([addLength floatValue] - fullminutes * 60); // fullseconds is an int
fullLength.text = [NSString stringWithFormat:#"%02d:%02d", fullminutes, fullseconds];
}
Hope this is helpful for someone else out there.
Related
I wish to display HH:MM at a UILabel when I adjust a custom slider. Currently my custom slider is returning me float values, for example, 2.89, 24.87... I wish to take the float value say 24.87 and change it to 24:52 I got everything working at the following code but I think it is not the most efficient way. Can anyone improve it? Thank you
- (void)slideValueChanged:(id)control
{
NSLog(#"Slider value changed: (%.2f,%.2f)",
_rangeSlider.lowerValue, _rangeSlider.upperValue);
lblStart.text = [NSString stringWithFormat:#"Start Time : %#", [self floatToTime:_rangeSlider.lowerValue]];
lblEnd.text = [NSString stringWithFormat:#"End Time : %#",[self floatToTime:_rangeSlider.upperValue]];
}
- (NSString*)floatToTime:(float)floatTime {
NSInteger iHour = floatTime;
CGFloat floatMin = floatTime - iHour;
NSString *sHour = [NSString stringWithFormat:#"%li", (long)iHour];
if (floatMin == 0.99) { //=== When the float is 0.99, convert it to 0, if not 60*0.99 = 59.4, will never get to 0
floatMin = 0;
}else{
floatMin = floatMin * 60;
}
NSInteger iMin = floatMin; //=== Take the integer part of floatMin
NSString *sMin = [[NSString alloc] init];
if (iMin <10){ //=== Take care if 0,1,2,3,4,5,6,7,8,9 to be 00,01,02,03...
sMin = [NSString stringWithFormat: #"0%li", iMin];
}else{
sMin = [NSString stringWithFormat: #"%li", iMin];
}
NSString *strFloatTime = [NSString stringWithFormat:#"%#:%#", sHour,sMin];
return strFloatTime;
}
You can use a format to show two digits, this simplifies creating a time string:
CGFloat time = 24.87;
int hours = fabs(time);
int minutes = (int)((time - hours) * 60.0);
NSLog(#"Time: %02d:%02d", hours, minutes);
Result: "Time: 24:52"
'02' is the number of digits.
So, I'm kind of new to Obj-c, and I have a strange crash happening with the following code :
- (NSMutableArray*)followNonBlackPixels:(int)startX withY:(int)startY
{
NSMutableArray* result;
NSMutableArray* adjacents = [self getAdjacents:startX withY:startY];
int r = 0;
int i = 0;
int tempX;
int tempY;
int max = [adjacents count];
CGPoint tempPoint;
while(i < max)
{
int tempX = (int)[[adjacents objectAtIndex:i] CGPointValue].x;
int tempY = (int)[[adjacents objectAtIndex:i] CGPointValue].y;
result = [self getAdjacents:tempX withY:tempY];
for(r = 0; r < [result count]; r++)
{
tempPoint = [[result objectAtIndex:r] CGPointValue];
//[adjacents addObject:[NSValue valueWithCGPoint:CGPointMake(tempPoint.x, tempPoint.y)]];
}
i++;
max = [adjacents count];
}
return adjacents;
}
This code runs fine, but as soon as I uncomment the line where I add an object to the "adjacents" NSMutableArray, then the program crashes.
The signature of the getAdjacents method is as follows:
- (NSMutableArray*)getAdjacents:(int)startX withY:(int)startY;
I'm developing a Cordova plugin under Windows so I do not have any debug info to provide... But maybe my mistake would be clear to an experienced obj-c developer ?
Thanks a lot for you help !
If you change your code to the following,
NSMutableArray *adjacents = [[NSMutableArray alloc] initWithArray:[[self getAdjacents:startX withY:startY] mutableCopy]];
I am getting this from webservice
"rateavg": "2.6111"
now i am getting this in a string.
How to do this that if it is coming 2.6 it will show 3 and if it will come 2.4 or 2.5 it will show 2 ?
How to get this i am not getting. please help me
Try This
float f=2.6;
NSLog(#"%.f",f);
Hope this helps.
I come up with this, a replica of your query:
NSString* str = #"2.611";
double duble = [str floatValue];
NSInteger final = 0;
if (duble > 2.5) {
final = ceil(duble);
}else{
final = floor(duble);
}
NSLog(#"%ld",(long)final);
So it a case of using either ceil or floor methods.
Edit: Since you want it for all doubles:
NSString* str = #"4.6";
double duble = [str floatValue];
NSInteger final = 0;
NSInteger temp = floor(duble);
double remainder = duble - temp;
if (remainder > 0.5) {
final = ceil(duble);
}else{
final = floor(duble);
}
NSLog(#"%ld",(long)final);
check this
float floatVal = 2.6111;
long roundedVal = lroundf(floatVal);
NSLog(#"%ld",roundedVal);
plz use this
lblHours.text =[NSString stringWithFormat:#"%.02f", [yourstrvalue doubleValue]];
update
NSString *a =#"2.67899";
NSString *b =[NSString stringWithFormat:#"%.01f", [a doubleValue]];
// b will contane only one vlue after decimal
NSArray *array = [b componentsSeparatedByString:#"."];
int yourRating;
if ([[array lastObject] integerValue] > 5) {
yourRating = [[array firstObject] intValue]+1;
}
else
{
yourRating = [[array firstObject] intValue];
}
NSLog(#"%d",yourRating);
Try below code I have tested it and work for every digits,
NSString *str = #"2.7";
NSArray *arr = [str componentsSeparatedByString:#"."];
NSString *firstDigit = [arr objectAtIndex:0];
NSString *secondDigit = [arr objectAtIndex:1];
if (secondDigit.length > 1) {
secondDigit = [secondDigit substringFromIndex:1];
}
int secondDigitIntValue = [secondDigit intValue];
int firstDigitIntValue = [firstDigit intValue];
if (secondDigitIntValue > 5) {
firstDigitIntValue = firstDigitIntValue + 1;
}
NSLog(#"final result : %d",firstDigitIntValue);
Or another solution - little bit short
NSString *str1 = #"2.444";
float my = [str1 floatValue];
NSString *resultString = [NSString stringWithFormat:#"%.f",my]; // if want result in string
NSLog(#"%#",resultString);
int resultInInt = [resultString intValue]; //if want result in integer
To round value to the nearest integer use roundf() function of math.
import math.h first:
#import "math.h"
Example,
float ValueToRoundPositive;
ValueToRoundPositive = 8.4;
int RoundedValue = (int)roundf(ValueToRoundPositive); //Output: 8
NSLog(#"roundf(%f) = %d", ValueToRoundPositive, RoundedValue);
float ValueToRoundNegative;
ValueToRoundNegative = -6.49;
int RoundedValueNegative = (int)roundf(ValueToRoundNegative); //Output: -6
NSLog(#"roundf(%f) = %d", ValueToRoundNegative, RoundedValueNegative);
Read doc here for more information:
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/roundf.3.html
NSString *value = #"1.23456";
float floatvalue = value.floatValue;
int rounded = roundf(floatvalue);
NSLog(#"%d",rounded);
if you what the round with greater value please use ceil(floatvalue)
if you what the round with lesser value please use floor(floatvalue)
You can round off decimal values by using NSNumberFormatter
There are some examples you can go through:
NSNumberFormatter *format = [[NSNumberFormatter alloc] init];
[format setPositiveFormat:#"0.##"];
NSLog(#"%#", [format stringFromNumber:[NSNumber numberWithFloat:25.342]]);
NSLog(#"%#", [format stringFromNumber:[NSNumber numberWithFloat:25.3]]);
NSLog(#"%#", [format stringFromNumber:[NSNumber numberWithFloat:25.0]]);
Corresponding results:
2010-08-22 15:04:10.614 a.out[6954:903] 25.34
2010-08-22 15:04:10.616 a.out[6954:903] 25.3
2010-08-22 15:04:10.617 a.out[6954:903] 25
NSString* str = #"2.61111111";
double value = [str doubleValue];
2.5 -> 3: int num = value+0.5;
2.6 -> 3: int num = value+0.4;
Set as your need:
double factor = 0.4
if (value < 0) value *= -1;
int num = value+factor;
NSLog(#"%d",num);
I have a sorted array, yrs, which is what it sounds like (a sorted array of years). This array holds 5 objects and each is similar to the object below:
__NSCFNumber * (int)1995 0x79fa3200
I'm trying to subtract the last item from the first item to get the date range:
int first_year = [yrs objectAtIndex:0];
int last_year = [yrs objectAtIndex:4];
NSInteger numberOfCols = ([last_year intValue] - [first_year intValue] ) + 1;
The values of the items in the array are as follows:
first_year int 2078365328 2078365328 where it should be 1995
last_year int 2083083520 2083083520 where it should be
numberOfCols NSInteger 328 328
I honestly have no idea what's going on here.
EDIT
NSMutableArray * years = [NSMutableArray array];
NSMutableArray * atts = [NSMutableArray array];
for(Treatment * treatment in items)
{
NSLog(#"%#",treatment.treatmentMolecule);
NSNumber * startYr = [NSNumber numberWithInt:treatment.startDate.yr];
NSNumber * endYr = [NSNumber numberWithInt:treatment.endDate.yr];
if((![years containsObject:startYr]) && (![startYr isEqual:#0])){
[years addObject:startYr];
}
if((![years containsObject:endYr]) && (![endYr isEqual:#0])){
[years addObject:endYr];
}
}
for(Attack * att in arrayAttack)
{
NSNumber * startYr = [NSNumber numberWithInt:att.yr];
if(![years containsObject:startYr])
[years addObject:startYr];
}
//sort yrs
yrs = [years sortedArrayUsingComparator:(NSComparator)^(NSNumber * yr1, NSNumber * yr2){
return [yr1 compare:yr2];
}];
This is wrong:
int first_year = [yrs objectAtIndex:0];
The element in the array is an instance of NSNumber. Try to replace it with this:
NSNumber *first_year = [yrs objectAtIndex:0];
Even better, you can use firstObject and lastObject instead of hard codes indices.
I would write it like this:
NSNumber *first_year = [yrs firstObject];
NSNumber *last_year = [yrs lastObject];
NSInteger numberOfCols = ([last_year integerValue] - [first_year integerValue] ) + 1;
You should do
int first_year = [[yrs objectAtIndex:0] intValue];
int last_year = [[yrs objectAtIndex:4] intValue];
to get the integer values saved in NSNumber.
I'm developing an iphone 4 app that filters the local media library by different criteria. I have been able to filter by song name, artist, and genre. Now I need to add a rating filter mechanism. I was thinking in something like "rating >= N stars" (N:0..5)
The code I use to filter is:
allMedia = [MPMediaQuery songsQuery];
MPMediaPropertyPredicate *mpp1 = [MPMediaPropertyPredicate predicateWithValue:#"2" forProperty:MPMediaItemPropertyRating comparisonType:MPMediaPredicateComparisonEqualTo];
[allMedia addFilterPredicate:mpp1];
But MPMediaPropertyPredicate does not allow to filter by MPMediaItemPropertyRating (and actually it works ok with artist and song title).
2011-05-12 11:37:39.060 Radio3[1525:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'MPMediaPropertyPredicate cannot filter using the rating property.'
I google by MPMediaItemPropertyRating but it seems that I should find an alternative approach to filter by track rating.
Can somebody give me a tip?
thanks
UPDATE: This is my code to solve this:
allMedia = [MPMediaQuery songsQuery];
//MPMediaPropertyPredicate *mpp1 = [MPMediaPropertyPredicate predicateWithValue:#"2" forProperty:MPMediaItemPropertyRating comparisonType:MPMediaPredicateComparisonEqualTo];
//MPMediaPropertyPredicate *mpp2 = [MPMediaPropertyPredicate predicateWithValue:#"Pop" forProperty:MPMediaItemPropertyGenre comparisonType:MPMediaPredicateComparisonContains];
//[allMedia addFilterPredicate:mpp1];
//[allMedia addFilterPredicate:mpp2];
//[myPlayer setQueueWithQuery:allMedia];
NSArray *itemsFromGenericQuery = [allMedia items];
NSMutableArray *mArray = [[NSMutableArray alloc] init];
int i = 0;
int j=0;
NSLog(#"itemCount: %d",[itemsFromGenericQuery count]);
float playsQuery = sliderPlays.value;
if(playsQuery == 20){playsQuery = 10000;}
NSLog(#"sliderRating.value %f sliderPlays.value %.1f", [sliderRating value], playsQuery);
while(i++ < 1000){
int trackNumber = arc4random() % [itemsFromGenericQuery count];
MPMediaItem *song = [itemsFromGenericQuery objectAtIndex:trackNumber];
NSString *artistName = [song valueForProperty: MPMediaItemPropertyArtist];
NSString *title = [song valueForProperty: MPMediaItemPropertyTitle];
NSString *rating = [song valueForKey:MPMediaItemPropertyRating];
double lengh = [[song valueForProperty:MPMediaItemPropertyPlaybackDuration] doubleValue];
NSNumber *playCount = [song valueForKey:MPMediaItemPropertyPlayCount];
if ([rating intValue] >= sliderRating.value && [playCount intValue] <= playsQuery) {
if(j++ > 50){break;}
NSLog (#"tracknumber: %d j: %d artistName: %# title: %# lengh: %.1f rating: %# playcount: %d",trackNumber, j, artistName, title, lengh, rating, [playCount intValue]);
[mArray addObject:song];
}
if(i++ > 1000)break;
}
MPMediaItemCollection *itemCol = [[MPMediaItemCollection alloc] initWithItems:mArray];
[myPlayer setQueueWithItemCollection:itemCol];
[myPlayer setShuffleMode: MPMusicShuffleModeSongs];
[myPlayer setRepeatMode: MPMusicRepeatModeNone];
MPMediaItemPropertyRating is a user-defined property, and according to the Apple docs:
User-defined properties cannot be used to build media property predicates.
One way to get around this would be to initially iterate over all the songs, store the ratings in a database (or something else) and sort the data from there.