非ゲームアプリケーションでのソーシャルサービスの導入

ソーシャルネットワークとさまざまな評価なしに現代の現実を想像することは不可能です。 この傾向に関連して、モバイルゲームとアプリケーションは積極的に「社会化」しています。 ただし、このような現象はゲームではありふれたものであり、論理的なものですが、非ゲームアプリケーションでソーシャルネットワークの機能を追加することは、誰にとっても明らかな解決策ではありません。 それにもかかわらず、長年のパートナーであり友人である音楽アプリケーション開発会社Music Paradiseは 、この一歩を踏み出すことを決定しました。 今日、私たちは「最初のソーシャルパッドをどうやって作ったのか」というコードネームのケースを共有しています。



「この記事では、 DJ Mix Pads 2音楽アプリケーションに基づいて音楽愛好家向けのソーシャルプラットフォームを作成した経験を共有したいと思います。



当初、このアプリケーションは、音楽愛好家が特別なスキルや知識がなくてもトラックを録音できるシンプルなツールセットでした。 数回クリックするだけで、プロに近い音で完成した作品を得ることができます。







多くの同様の製品から目立つように、私たちは競争力のある要素でプレイし、作曲のプロセスをより集中的にすることにしました。 自分の中でミュージシャンを発見することは、人々に自分の作品を他のユーザーと共有したり、他のユーザーを評価したり、トップになったり、音楽に興味のあるグループに参加したり、アプリケーションの新しい機能を発見したりして評価を上げる機会を与えると、より興味深いものになります。



この記事では、サーバーでの作業のさまざまな側面に触れ、ソーシャルコンポーネントの導入に必要ないくつかの追加機能、およびそれらが製品に実装された方法について説明します。



クライアントとサーバーの相互作用



サーバーAPIの操作は、POSTおよびGETリクエストを介して実行されます。 ここで、それらを使用して作業を構成するために使用したトリックを詳細に検討します。



HTTPリクエストの形成について話すのは意味がありません。Googleはすでに関連情報でいっぱいであり、githubで多くの有用なライブラリを見つけることができます。



したがって、ユーザーに人気のあるトラックのリストをどのように受け取ったかの例を使用して、サーバーからの応答で作業をよりよく分析します。 トラックのリストは次の形式で提供されます。



{ data = (); success = 1; }
      
      





または、この場合、リクエストが正しくないか、何らかのエラーが発生した場合:



 { error = "Error description"; success = 0; }
      
      





答えを解析するには、次の構造を使用します。



 NSDictionary *answer = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];// data -     if([[answer objectForKey:@"success"] boolValue]){ NSMutableArray *dataArray = [answer objectForKey:@"data"]; [self doSomeStuff:dataArray]; } else{ if([answer objectForKey:@"error"]) NSLog(@"%@",[answer objectForKey:@"error"]); }
      
      





画像転送



アプリケーションに登録するとき、ユーザーは自分自身にアバターを付ける機会があります。 それぞれ、画像がサーバーとの間でどのように送信されるかについての疑問が生じました。



選択した画像循環メカニズムは非常に独特です。 最も簡単な解決策は、ファイル自体をPOSTリクエストとして転送し、必要に応じてサーバー側でファイルへのリンクを取得することです。 このようにして、ユーザーがサーバーにアップロードするオーディオファイルのストレージを実装しました。



ただし、画像をbase64文字列として転送することにしました。 これを行うには、クライアント側で次の文字列変換メソッドが使用されます。



まず、必要に応じて、画像を文字列に変換し、同時にサイズ変更します。 この時点で画像はすでに正方形であることに言及する価値があります。



 -(NSString *)imageToNSString:(UIImage *)image { if(!image) return nil; if(image.size.width>250&image.size.height>250) image = [self imageWithImage:image scaledToSize:CGSizeMake(250, 250)]; NSData *imageData = UIImagePNGRepresentation(image); return [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; } - (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContext(newSize); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
      
      





次に、文字列を画像に変換します。



 -(UIImage *)stringToUIImage:(NSString *)string { if(string==nil) return nil; NSData *data = [[NSData alloc]initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters]; return [UIImage imageWithData:data]; }
      
      





一見したところ、このアプローチは最も効果的とは思えないかもしれません。二重の作業を行い、画像を前後に変換する必要があるからです。 しかし、私たちにとって、このような小さな合併症は正当化されました。最終的には、私たちの生活を大幅に簡素化し、開発プロセスを加速しました。



ページネーションについて少し



この問題は、私たちの社会革新がすでに人気を博し始めていたときに、予想外に、そして他の問題よりもやや遅れて起こりました。 人々は1日に非常に多くのトラックをアップロードし始め、サーバー上のオーディオファイルの配列は容赦なく増大しました。これはすべて、トップリストを取得する際に問題を引き起こしました。 リスト全体を一度に処理しようとすると、アプリケーションがフリーズし、エラーがスローされます。 コンテンツの部分的なダウンロードに切り替える必要があることが明らかになりました。つまり、ページネーションを導入することです。







リストは標準的にUITableViewを使用して作成され、サーバーからデータを受信したときに新しいセルをロードする方法を開発する必要がありました。



 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ if(indexPath.row == self.tableContentArray.count-1 && !self.isFullContent) { [self getContentFrom:self.tableContentArray.count withCount:10]; } }
      
      





まず、次のことを確認します。



-このセルは表示可能な最後のセルです。

-このコントローラーに表示されるすべてのコンテンツを受け取ったかどうか。



計算は次のとおりです。要求した数よりも少ないレコード(この場合は10未満)を受け取った場合、この時点で変数isFullContentをtrueとしてマークします。



アプリ内通知



ユーザーがアプリケーション内で自分のアカウントのステータス(いいね!、プレイなどの数)に関する完全な情報にアクセスできるようにしたかったのです。 このために、ローカル通知システムが導入されました。 彼女は次の動作原理を持っています-ユーザーがアプリケーションに入ると、現在の状態を保存します:



 [[NSUserDefaults standardUserDefaults] setInteger:user.countOfLikes forKey:@"countOfLikes"]; [[NSUserDefaults standardUserDefaults] setInteger:user.countOfLikes integerValue] forKey:@"countOfListens"]; [[NSUserDefaults standardUserDefaults] setInteger:user.level forKey:@"countOfLevels"];
      
      





次の入力で、これらの値はサーバーから受信したデータでチェックされます。 それらが一致しない場合、ユーザーに進捗があることを知らせるローカル通知を表示します。 このような良いニュースは、ユーザーエクスペリエンスにプラスの影響を与えます。



 CongratsCustomPush *push = [[CongratsCustomPush alloc] initInController:[self topViewController] withTitle:@"Changes since your last visit.\nGood job!" withLevel:countOfLevels withLikes:countOfLikes andWithListens:countOfListens]; [push showAnimated:YES];
      
      









実績



成果は、アプリケーションのすべての機能を使用することに対する興味深いコンテンツおよびユーザーの報酬であるだけでなく、分析によって提供されるデータに加えて、視聴者の欲求についてさらに学ぶ良い方法でもあります。







現時点では、アプリケーションには9つの成果があります。





実績の作成はクライアントのビジネスであり、サーバーは実績に関する情報と一部の統計(たとえば、ユーザーがアプリケーションに費やした時間)のみを保存します



実績に関するアラートを送信する場合、特定のユーザー向けのリモートPUSH通知のシステムが使用されます。 ユーザーを識別するために、最後のログインが行われたデバイスのUUIDを保存し、PUSH通知を受信すると、状況に応じて2つの方法のいずれかを使用します。



ユーザーが現在アプリケーションにいない場合、達成された成果に関する情報を含む標準通知を受け取ります-これが最初の方法です。



2番目の方法はより複雑です。 ユーザーが現在アプリケーションにいる場合、AppDelegateメソッドで受信したメッセージをインターセプトします。



 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
      
      







現在のViewController'eに表示します。



おわりに



最終的にどの追加機能がサーバーの使用をもたらしたかを要約します。





PS連中はまた、面白い傾向に気づいたと言っています。このプロジェクトの主要な開発者は、作業を開始してから約2〜3か月で結婚します。 現時点では、スコアはこの「信念」を支持して2-0です。 したがって、個人的な生活に根本的な変化が必要な場合は、アプリケーションに同様のプロジェクトを実装してみてください。



All Articles