Control reach end of non-void function - objective-c

Please consider following code:
-(NSString*)getNextOvulationString{
if (self.daysToNextOvulation < 0){
return [NSString stringWithFormat:#"Овуляция была %li дней назад", labs(self.daysToNextOvulation)];
} else if (self.daysToNextOvulation == 0){
return [NSString stringWithFormat:#"Овуляция началась"];
} else if (self.daysToNextOvulation > 0){
return [NSString stringWithFormat:#"Овуляция началась"];
}
}
There is 3 cases, and obvious, we will get one guaranteed.
Still, compiler not allow me to build, because of error:
Control reach end of non-void function
How to fix that?

Since the final condition is the exhaustive case, change the final else if to an else and call it a day. If you want, add your condition as a same-line comment to keep it clear.
The end result would be something like this:
- (NSString *)getNextOvulationString
{
if (self.daysToNextOvulation < 0)
{
return [NSString stringWithFormat:#"Овуляция была %li дней назад", labs(self.daysToNextOvulation)];
}
else if (self.daysToNextOvulation == 0)
{
return [NSString stringWithFormat:#"Овуляция началась"];
}
else // self.daysToNextOvulation > 0
{
return [NSString stringWithFormat:#"Овуляция началась"];
}
}
You could also drop the final else altogether like this:
- (NSString *)getNextOvulationString
{
if (self.daysToNextOvulation < 0)
{
return [NSString stringWithFormat:#"Овуляция была %li дней назад", labs(self.daysToNextOvulation)];
}
else if (self.daysToNextOvulation == 0)
{
return [NSString stringWithFormat:#"Овуляция началась"];
}
// self.daysToNextOvulation > 0
return [NSString stringWithFormat:#"Овуляция началась"];
}
And since the last two conditions both return the same thing you could even write it this way:
- (NSString *)getNextOvulationString
{
if (self.daysToNextOvulation < 0)
{
return [NSString stringWithFormat:#"Овуляция была %li дней назад", labs(self.daysToNextOvulation)];
}
else // self.daysToNextOvulation >= 0
{
return [NSString stringWithFormat:#"Овуляция началась"];
}
}
Or this way, again dropping the else entirely:
- (NSString *)getNextOvulationString
{
if (self.daysToNextOvulation < 0)
{
return [NSString stringWithFormat:#"Овуляция была %li дней назад", labs(self.daysToNextOvulation)];
}
// self.daysToNextOvulation >= 0
return [NSString stringWithFormat:#"Овуляция началась"];
}
Note: All of the above pieces of code are functionally equivalent given the current conditions and return values.

You need to add else at last to return the NSString, so change you if condition like this.
-(NSString*)getNextOvulationString{
if (self.daysToNextOvulation < 0){
return [NSString stringWithFormat:#"Овуляция была %li дней назад", labs(self.daysToNextOvulation)];
}
else if (self.daysToNextOvulation == 0){
return [NSString stringWithFormat:#"Овуляция началась"];
}
else //No need to compare here
return [NSString stringWithFormat:#"Овуляция началась"];
}
}

Related

How to find the recently viewed records using objective C

Im working on recently viewed functionality, I have to create one model class of History. In history i have FileName,Title,ActivityName. Im using 2 methods to store the filename and title.
History.h
-(BOOL)history:(NSString *)sFile activityName:(NSString *)activityName title:(NSString *)title GID_ID:(NSString *)dataGID_ID;
-(id)getHistoryInstance;
-(BOOL)addNewHistory:(Histrory *)history;
-(NSMutableArray *)recentlyViewedDict;
History.m
+(Histrory *)getSharedInstance{
if (!sharedInstance) {
sharedInstance = [[super allocWithZone:NULL]init];
[sharedInstance recentlyViewedDict];
}
return sharedInstance;
}
-(NSMutableArray *)recentlyViewedDict {
return recentlyViewedDict;
}
-(BOOL)history:(NSString *)sFile activityName:(NSString *)activityName title:(NSString *)title GID_ID:(NSString *)dataGID_ID
{
_sFile = sFile;
_titleName = title ;
_dataGID_ID = dataGID_ID;
_activityName = activityName;
[self performSelector:#selector(addNewHistory:) withObject:self afterDelay:0.1];
return YES;
}
-(id)getHistoryInstance {
NSLog(#"RECENTLY VIEWED DICY %#", recentlyViewedDict);
if ([recentlyViewedDict count] == 0) {
recentlyViewedDict = [[NSMutableArray alloc]init];
}
else {
return recentlyViewedDict;
}
return recentlyViewedDict;
}
-(BOOL)addNewHistory:(Histrory *)his {
BOOL val = false;
recentlyViewedDict = [self getHistoryInstance];
if ([recentlyViewedDict count] != 0) {
for (int i = 0 ; i < [recentlyViewedDict count]; i++) {
Histrory *one = (Histrory *) recentlyViewedDict[i];
if ([his.getData_GIDID isEqualToString:one.getData_GIDID]) {
val = false;
[recentlyViewedDict removeObjectAtIndex:i];
}
}
}
else {
NSString *addData = [NSString stringWithFormat:#"%#,%#,%#,%#",his.getsFile,his.getTitle,his.getAcivityName,his.getData_GIDID];
[recentlyViewedDict addObject:addData];
}
if ([recentlyViewedDict count] > 11) {
[recentlyViewedDict removeObjectAtIndex:0];
}
NSLog(#"Recently Viewed %#", recentlyViewedDict);
return YES;
}
In this every time i have to store only 1 file.I want to store at least 10 records, if 11 record inserting then 1 record will be deleted using below method.
if ([recentlyViewedDict count] > 11) {
[recentlyViewedDict removeObjectAtIndex:0];
}
How can i store each time recent record.
ContactDetails.m
historyObj = [[Histrory alloc]init];
[historyObj history:sFile activityName:activityName title:contactName GID_ID:contactGID_ID];
Im calling this method every time to visit details classes. this method works only one time like, it will store only first record, you are visited second time it is showing nil value. How can store the multiple detail classes to store each record.thanks in advance.

Always returning null in NSString return function

I have the following code where I want to convert decimal odds to fractional odds. However the function findNearestWholeInteger always returns null.
- (NSString *)displayOddWithFormat:(NSString *)decimalOdd {
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"FractionalOdds"] == YES) {
float oddsF = decimalOdd.floatValue;
oddsF = oddsF - 1.0f;
return [self findNearestWholeInteger:oddsF andInitial:oddsF andBottom:1];
} else {
return odd;
}
}
- (NSString *)findNearestWholeInteger:(float)odds andInitial:(float)initial andBottom:(float)bottom {
NSNumber *numberValue = [NSNumber numberWithFloat:odds];
NSString *floatString = [numberValue stringValue];
NSArray *floatStringComps = [floatString componentsSeparatedByString:#"."];
if (floatStringComps.count == 1) {
return [NSString stringWithFormat:#"%.f/%.f", odds, bottom];
} else {
bottom += 1;
odds += initial;
[self findNearestWholeInteger:odds andInitial:initial andBottom:bottom];
return nil;
}
}
Any ideas where I need to adapt my code? Thanks in advance!
Don't you want:
return [self findNearestWholeInteger:odds andInitial:initial andBottom:bottom];
//return nil;
(not that I really understand what the method is doing).

Xcode: How do I end a 2 player turn based multiplayer match with a winner and loser using GameCenter?

I've had a bit of trouble finding any information on this and all the code samples I come across are based on the match ending in a tie for all players. In my 2 player turn based game I want to be able to end the match with a winner and loser. With the below code I've written the match always ends with the same result for both players, if its a win then both player 1 and 2 win, if its a loss both player 1 and 2 loose... any help? Thank you.
if (gameOver == true) {
if (GameWinner == 0) {
GKTurnBasedParticipant *player0 = [currentMatch.participants objectAtIndex:0];
player0.matchOutcome = GKTurnBasedMatchOutcomeWon;
GKTurnBasedParticipant *player1 = [currentMatch.participants objectAtIndex:1];
player1.matchOutcome = GKTurnBasedMatchOutcomeLost;
[currentMatch endMatchInTurnWithMatchData:data completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];
testlabel.text = #"Player 1 Wins!";
} else if (GameWinner == 1) {
GKTurnBasedParticipant *player0 = [currentMatch.participants objectAtIndex:0];
player0.matchOutcome = GKTurnBasedMatchOutcomeLost;
GKTurnBasedParticipant *player1 = [currentMatch.participants objectAtIndex:1];
player1.matchOutcome = GKTurnBasedMatchOutcomeWon;
[currentMatch endMatchInTurnWithMatchData:data completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];
testlabel.text = #"Player 2 Wins!";
} else if (GameWinner == 2) {
for (GKTurnBasedParticipant *part in currentMatch.participants) {
part.matchOutcome = GKTurnBasedMatchOutcomeTied;
}
[currentMatch endMatchInTurnWithMatchData:data completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];
testlabel.text = #"Tie Game!";
} else {
testlabel.text = #"Your turn is over.";
}
This sounds similar to this SO Question, try:
GKTurnBasedParticipant *curr = currentMatch.currentParticipant;
NSUInteger currentIndex = [currentMatch.participants indexOfObject:currentMatch.currentParticipant];
NSUInteger nextIndex = (currentIndex + 1) % [currentMatch.participants count];
GKTurnBasedParticipant *next = [currentMatch.participants objectAtIndex:nextIndex];
if (currScore < otherScore)
{
// Curr player lost
curr.matchOutcome = GKTurnBasedMatchOutcomeLost;
next.matchOutcome = GKTurnBasedMatchOutcomeWon;
}
else if (currScore == otherScore)
{
// Tied
curr.matchOutcome = GKTurnBasedMatchOutcomeTied;
next.matchOutcome = GKTurnBasedMatchOutcomeTied;
}
else
{
// Won
curr.matchOutcome = GKTurnBasedMatchOutcomeWon;
next.matchOutcome = GKTurnBasedMatchOutcomeLost;
}

How to Compare between Objects property's then sort using ( sortusingselector:#selector)?

I'm trying to write a simple function == " compareGPA" that compares between the GPA of two students , then sorting them in descending order by using selector as that : [array sortUsingSelector:#selector(compareGPA:)];
I've tried to write the function in 2 different ways , but nothing works ,
First way :
+(NSComparisonResult) compareGPA: (Student *) OtherStudent{
Student *tmp =[Student new];
if ([OtherStudent getGpa] < [tmp getGpa]){
return (NSComparisonResult) tmp;
}
if([tmp getGpa] < [OtherStudent getGpa])
{ return (NSComparisonResult) OtherStudent; }
}
2nd way :
+(NSComparisonResult) compareGPA: (Student *) OtherStudent{
NSComparisonResult res;
res = [[self getGpa] compare: [OtherStudent getGpa]];
return res;
Switch (res)
{
case NSOrderedAscending:
return NSOrderedDescending;
break;
case NSOrderedDescending:
return NSOrderedAscending;
break;
default:
return NSOrderedSame;
break;
}
}
Output : Nothing
Any suggestions ??
You should make your caparison method
+(NSComparisonResult) compareGPA: (Student *) OtherStudent
an instance method (not a class method, + becomes -), so that it compares the receiver's GPA with OtherStudent's GPA), like this
-(NSComparisonResult) compareGPA: (Student *) OtherStudent {
// if GPA is a float int double ...
if ([OtherStudent getGpa] == [self getGpa]
return NSOrderedSame;
if ([OtherStudent getGpa] < [self getGpa]){
return NSOrderedAscending;
return NSOrderedDescending;
// if GPA is an object which responds to the compare: message
return [[self getGPA] compare:[OtherStudent getGPA]]
}
Then sort your array of Student objects using selector #selector(compareGPA:)
As you're using compare: I have to assume that getGPA returns an NSNumber, in which case all you'd need would be this:
NSArray *students = ...;
NSArray *sortedStudents = [students sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"getGPa" ascending:NO]]];
If getGPA however was to return some primitice C type (such as float in your case), then you could do it this way:
NSArray *students = ...;
NSArray *sortedStudents = [students sortedArrayUsingComparator:^NSComparisonResult(Studen *student1, Studen *student2) {
float student1GPA = [student1 getGPA];
float student2GPA = [student2 getGPA];
if (student1GPA < student2GPA) {
return NSOrderedAscending;
} else if (student1GPA > student2GPA) {
return NSOrderedDescending;
}
return NSOrderedSame;
}];
If if you need the compareGPA: elsewhere, too:
- (NSComparisonResult) compareGPA:(Studen *otherStudent) {
float student1GPA = [self getGPA];
float student2GPA = [otherStudent getGPA];
if (student1GPA < student2GPA) {
return NSOrderedAscending;
} else if (student1GPA > student2GPA) {
return NSOrderedDescending;
}
return NSOrderedSame;
}

Send email to multiple recipients with SKPSMTPMessage?

I need to send email in background, so I have to use the library named: SMTP. And the main class I used is: SKPSMTPMessage. The problem is "ccEmail", when I add more than 2 recipients, it can't send email. (that takes too long time to go to delegate methods). It works well with recipient <= 2.
smtpEmail.ccEmail = #"xyz#gmail.com, xyz1#gmail.com, xyz2#gmail.com";
Anyone knows this, please help me. Thanks you so much !
There is my changes in the parseBuffer function:
case kSKPSMTPWaitingFromReply:
{
if ([tmpLine hasPrefix:#"250 "]) {
if (!multipleRcptTo) {
NSMutableString *multipleRcptToString = [NSMutableString string];
[multipleRcptToString appendString:[self formatAddresses:toEmail]];
[multipleRcptToString appendString:[self formatAddresses:ccEmail]];
[multipleRcptToString appendString:[self formatAddresses:bccEmail]];
multipleRcptTo = [[multipleRcptToString componentsSeparatedByString:#"\r\n"] mutableCopy];
[multipleRcptTo removeLastObject];
}
if ([multipleRcptTo count] > 0) {
NSString *rcptTo = [NSString stringWithFormat:#"%#\r\n", [multipleRcptTo objectAtIndex:0]];
[multipleRcptTo removeObjectAtIndex:0];
//DEBUGLOG(#"C: %#", rcptTo);
if (CFWriteStreamWriteFully((CFWriteStreamRef)outputStream, (const uint8_t *)[rcptTo UTF8String], [rcptTo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) < 0)
{
error = [outputStream streamError];
encounteredError = YES;
}
else
{
[self startShortWatchdog];
}
}
if ([multipleRcptTo count] == 0) {
sendState = kSKPSMTPWaitingToReply;
}
}
break;
}
and add this into header:
NSMutableArray *multipleRcptTo;
EDIT : Also change below method as multipleRcptTo is used as NSMutableString which is local declaration :
- (NSString *)formatAddresses:(NSString *)addresses {
NSCharacterSet *splitSet = [NSCharacterSet characterSetWithCharactersInString:#";,"];
NSMutableString *multipleRcpt = [NSMutableString string];
if ((addresses != nil) && (![addresses isEqualToString:#""])) {
if( [addresses rangeOfString:#";"].location != NSNotFound || [addresses rangeOfString:#","].location != NSNotFound ) {
NSArray *addressParts = [addresses componentsSeparatedByCharactersInSet:splitSet];
for( NSString *address in addressParts ) {
[multipleRcpt appendString:[self formatAnAddress:address]];
}
}
else {
[multipleRcpt appendString:[self formatAnAddress:addresses]];
}
}
return(multipleRcpt);
}
SKPSMTPMessage sends to the SMTP address all at once, and must send one by one.