I create a custom UIActivityViewController but when I load the icons that I do makes me see gray and you are pretty much loaded correctly, someone did it happen? how you have remedied?
ActivityViewCustomActivity *ca = [[ActivityViewCustomActivity alloc]init];
ca.service = #"avanti";
ca.image = image;
ca.act = #"com.avanti.app";
ActivityViewCustomActivity *fa = [[ActivityViewCustomActivity alloc]init];
fa.service = #"facebook";
fa.image = image;//[UIImage imageNamed:#"icon-facebook.jpg"];
fa.act = #"com.facebook.app";
ActivityViewCustomActivity *tw = [[ActivityViewCustomActivity alloc]init];
tw.service = #"twitter";
tw.image = image;
tw.act = #"com.twitter.app";
UIActivityViewController *activityVC =
[[UIActivityViewController alloc] initWithActivityItems:items
applicationActivities:#[ca,fa,tw]];
activityVC.excludedActivityTypes = #[UIActivityTypePostToTwitter,UIActivityTypePostToFacebook,UIActivityTypeMail,UIActivityTypePostToWeibo, UIActivityTypeAssignToContact, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeSaveToCameraRoll];
activityVC.completionHandler = ^(NSString *activityType, BOOL completed)
{
if ([activityType isEqualToString:#"com.avanti.app"]) {
NSLog(#" activityType: %#", activityType);
NSLog(#" completed: %i", completed);
NSString *name = [q objectAtIndex:indexPath.row];
UIStoryboard *storyboar = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
ListViewController *list = [storyboar instantiateViewControllerWithIdentifier:#"ListViewController"];
list.ide = ide;
list.canale = name;
[self.navigationController pushViewController:list animated:YES];
}
else if ([activityType isEqualToString:#"com.facebook.app"]){
NSLog(#" activityType: %#", activityType);
NSLog(#" completed: %i", completed);
UIActionSheet *action = [[UIActionSheet alloc]initWithTitle:#"Facebook" delegate:self cancelButtonTitle:#"Annulla" destructiveButtonTitle:#"Vuoi pubblicarlo ?" otherButtonTitles:#"ok", nil];
action.actionSheetStyle = UIActionSheetStyleDefault;
[self actionSheet:action clickedButtonAtIndex:2];
[action showInView:[self.view window]];
}
else if ([activityType isEqualToString:#"com.twitter.app"]){
NSLog(#" activityType: %#", activityType);
NSLog(#" completed: %i", completed);
[self shareTwitter];
}
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
NSLog(#"ipad");
}
else
{
[self presentViewController:activityVC animated:YES completion:nil];
}
}
e l'activity è così
- (NSString *)activityType
{
return act;
}
- (NSString *)activityTitle
{
return service;
}
- (UIImage *)activityImage
{
// CGRect rect = CGRectMake(0.0f, 0.0f, 85.0f, 85.0f);
// UIGraphicsBeginImageContext(rect.size);
//
// rect = CGRectInset(rect, 15.0f, 15.0f);
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:10.0f];
// [path stroke];
//
// rect = CGRectInset(rect, 0.0f, 10.0f);
// [service drawInRect:rect withFont:[UIFont fontWithName:#"Futura" size:15.0f] lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter];
//
// UIImage *imag = UIGraphicsGetImageFromCurrentImageContext();
//
// UIGraphicsEndImageContext();
// //UIImage *ima = [UIImage imageNamed:#"facebook.jpg"];
// return imag;
UIImage *ima = [UIImage imageNamed:#"Icon_Facebook.png"];
return ima;
// if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
// {
// return [UIImage imageNamed:#"Facebook_43x43"];
// }
// else
// {
// return image;
// }
}
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
NSLog(#"%s", __FUNCTION__);
for (id obj in activityItems) {
if ([obj isKindOfClass:[NSString class]]) {
return YES;
}
}
return NO;
}
- (void)prepareWithActivityItems:(NSArray *)activityItems
{
NSLog(#"%s",__FUNCTION__);
}
- (UIViewController *)activityViewController
{
NSLog(#"%s",__FUNCTION__);
return nil;
}
- (void)performActivity
{
// This is where you can do anything you want, and is the whole reason for creating a custom
// UIActivity
[self activityDidFinish:YES];
}
+ (UIActivityCategory)activityCategory
{
return UIActivityCategoryShare;
}
and the screenshot is here http://i57.tinypic.com/332vtjo.png
and .h is
#import <UIKit/UIKit.h>
#interface ActivityViewCustomActivity : UIActivity
#property (nonatomic, strong) NSString *service;
#property (nonatomic, strong) UIImage *image;
#property (nonatomic, strong) NSString *act;
- (NSString *)activityType;
- (NSString *)activityTitle;
- (UIImage *)activityImage;
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems;
- (void)prepareWithActivityItems:(NSArray *)activityItems;
- (UIViewController *)activityViewController;
- (void)performActivity;
+ (UIActivityCategory)activityCategory;
#end
Try to add _ to your activityImage function
Something like
- (UIImage *)_activityImage
{
return [UIImage imageNamed:#"Icon_Facebook.png"];
}
Related
I have a problem with direction of messages in JSQMessage.
When I write and send message all good with direction but when I restart app or else that some messages changes its direction.
Its my code
#import "ChatViewController.h"
#import <AVKit/AVKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "JSQMessagesCollectionViewFlowLayout.h"
#import "JSQMessages.h"
#import "JSQPhotoMediaItem.h"
#import "JSQLocationMediaItem.h"
#import "JSQVideoMediaItem.h"
#import "JSQMessagesMediaViewBubbleImageMasker.h"
#import "JSQMessagesAvatarImage.h"
#import "JSQMessagesAvatarImageFactory.h"
#import <JSQMessagesBubbleImage.h>
#import <JSQMessagesBubbleImageFactory.h>
#import <FirebaseDatabase/FirebaseDatabase.h>
#import <FirebaseStorage/FirebaseStorage.h>
#import <FirebaseAuth/FirebaseAuth.h>
#interface ChatViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property (strong, nonatomic) NSMutableArray *messages;
#property (strong, nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageView;
#property (strong, nonatomic) JSQMessagesBubbleImage *incomingBubbleImageView;
#property (strong, nonatomic) FIRDatabaseReference *databaseReference;
#property (strong, nonatomic) NSString *convoId;
#end
#implementation ChatViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = self.senderDisplayName;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"backgroundChat"]];
imageView.alpha = 0.5;
self.collectionView.backgroundView = imageView;
_messages = [NSMutableArray new];
_databaseReference = [[FIRDatabase database] reference];
[self setupBubbles];
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
NSString *receiverId = [_receiverData objectForKey:#"uId"];
NSString *receiverIdFive = [receiverId substringToIndex:5];
NSString *senderIdFive = [self.senderId substringToIndex:5];
if (senderIdFive > receiverIdFive) {
_convoId = [NSString stringWithFormat:#"%#%#", senderIdFive, receiverIdFive];
} else {
_convoId = [NSString stringWithFormat:#"%#%#", receiverIdFive, senderIdFive];
}
[self observeMessages];
}
- (IBAction)backButtonAction:(id)sender {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *viewiewController = [mainStoryboard instantiateViewControllerWithIdentifier:#"HomeView"];
[self presentViewController:viewiewController animated:true completion:nil];
}
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
return _messages[indexPath.item];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _messages.count;
}
- (void)setupBubbles {
JSQMessagesBubbleImageFactory *factory = [JSQMessagesBubbleImageFactory new];
_outgoingBubbleImageView = [factory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleBlueColor]];
_incomingBubbleImageView = [factory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
}
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
JSQMessage *message = _messages[indexPath.item];
if (message.senderId == self.senderId) {
return _outgoingBubbleImageView;
} else {
return _incomingBubbleImageView;
}
}
- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
- (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
JSQMessagesCollectionViewCell *cell = [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
JSQMessage *message = _messages[indexPath.item];
if (message.senderId == self.senderId) {
cell.textView.textColor = [UIColor whiteColor];
} else {
cell.textView.textColor = [UIColor blackColor];
}
return cell;
}
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapMessageBubbleAtIndexPath:(NSIndexPath *)indexPath {
JSQMessage *message = _messages[indexPath.row];
if (message.isMediaMessage) {
JSQVideoMediaItem *mediaItem = (JSQVideoMediaItem *)message.media;
if (mediaItem != nil) {
AVPlayer *player = [AVPlayer playerWithURL:mediaItem.fileURL];
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
playerViewController.player = player;
[self presentViewController:playerViewController animated:true completion:nil];
}
}
}
- (void)didPressSendButton:(UIButton *)button withMessageText:(NSString *)text senderId:(NSString *)senderId senderDisplayName:(NSString *)senderDisplayName date:(NSDate *)date {
FIRDatabaseReference *itemReference = [[[_databaseReference child:#"message"] child:[NSString stringWithFormat:#"%#", _convoId]] childByAutoId];
NSDictionary *messageItem = #{#"text":text, #"senderId":senderId, #"mediaType":#"TEXT"};
[itemReference setValue:messageItem];
[JSQSystemSoundPlayer jsq_playMessageSentSound];
[self finishSendingMessageAnimated:YES];
}
- (void)didPressAccessoryButton:(UIButton *)sender {
UIAlertController *sheet = [UIAlertController alertControllerWithTitle:#"Send file" message:#"Appearance media files in messages depend of your internet speed" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *image = [UIAlertAction actionWithTitle:#"Image Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self getMediaFrom:kUTTypeImage];
}];
UIAlertAction *video = [UIAlertAction actionWithTitle:#"Video Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self getMediaFrom:kUTTypeMovie];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[sheet addAction:image];
[sheet addAction:video];
[sheet addAction:cancel];
sheet.popoverPresentationController.sourceView = self.view;
sheet.popoverPresentationController.sourceRect = CGRectMake(CGRectGetMinX(self.view.frame), CGRectGetMaxY(self.view.frame), sheet.accessibilityFrame.size.width, sheet.accessibilityFrame.size.height);
[self presentViewController:sheet animated:true completion:nil];
}
- (void)getMediaFrom:(CFStringRef)type {
UIImagePickerController *picker = [UIImagePickerController new];
picker.delegate = self;
picker.mediaTypes = #[(__bridge NSString *)type];
[self presentViewController:picker animated:true completion:nil];
}
- (void)observeMessages {
FIRDatabaseQuery *messagesQuery = [[_databaseReference child:[NSString stringWithFormat:#"message/%#", _convoId]] queryLimitedToLast:25];
[messagesQuery observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
if (snapshot.value[#"senderId"] != nil) {
NSString *ID = snapshot.value[#"senderId"];
NSString *mediaType = snapshot.value[#"mediaType"];
if ([mediaType isEqual:#"TEXT"]) {
NSString *text = snapshot.value[#"text"];
[_messages addObject:[JSQMessage messageWithSenderId:ID displayName:#"" text:text]];
} else if ([mediaType isEqual:#"PHOTO"]) {
NSString *image = snapshot.value[#"fileUrl"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:image]];
JSQPhotoMediaItem *photoItem = [[JSQPhotoMediaItem alloc] initWithImage:[UIImage imageWithData:data]];
[_messages addObject:[JSQMessage messageWithSenderId:ID displayName:#"" media:photoItem]];
} else if ([mediaType isEqual:#"VIDEO"]) {
NSString *video = snapshot.value[#"fileUrl"];
JSQVideoMediaItem *videoItem = [[JSQVideoMediaItem alloc] initWithFileURL:[NSURL URLWithString:video] isReadyToPlay:true];
[_messages addObject:[JSQMessage messageWithSenderId:ID displayName:#"" media:videoItem]];
}
[self finishReceivingMessage];
}
}];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage *image = info[UIImagePickerControllerOriginalImage];
NSURL *video = info[UIImagePickerControllerMediaURL];
if (image != nil) {
[self sendMedia:image and:nil];
} else if (video != nil) {
[self sendMedia:nil and:video];
}
[picker dismissViewControllerAnimated:true completion:nil];
[self.collectionView reloadData];
}
- (void)sendMedia:(UIImage *)image and:(NSURL *)video {
if (image != nil) {
NSString *filePath = [NSString stringWithFormat:#"%#/%f", [FIRAuth auth].currentUser, [NSDate date].timeIntervalSinceReferenceDate];
NSData *data = UIImageJPEGRepresentation(image, 0.3);
FIRStorageMetadata *metadata = [FIRStorageMetadata new];
metadata.contentType = #"image/jpg";
[[[[FIRStorage storage] reference] child:filePath] putData:data metadata:metadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
if (error != nil) {
NSLog(#"%#", error.localizedDescription);
return;
}
NSString *fileURL = [metadata downloadURLs][0].absoluteString;
FIRDatabaseReference *newMessage = [[_databaseReference child:[NSString stringWithFormat:#"message/%#", _convoId]] childByAutoId];
NSDictionary *messageItem = #{#"fileUrl":fileURL, #"senderId":self.senderId, #"mediaType":#"PHOTO"};
[newMessage setValue:messageItem];
}];
} else if (video != nil) {
NSString *filePath = [NSString stringWithFormat:#"%#/%f", [FIRAuth auth].currentUser, [NSDate date].timeIntervalSinceReferenceDate];
NSData *data = [NSData dataWithContentsOfURL:video];
FIRStorageMetadata *metadata = [FIRStorageMetadata new];
metadata.contentType = #"video/mp4";
[[[[FIRStorage storage] reference] child:filePath] putData:data metadata:metadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
if (error != nil) {
NSLog(#"%#", error.localizedDescription);
return;
}
NSString *fileURL = [metadata downloadURLs][0].absoluteString;
FIRDatabaseReference *newMessage = [[_databaseReference child:[NSString stringWithFormat:#"message/%#", _convoId]] childByAutoId];
NSDictionary *messageItem = #{#"fileUrl":fileURL, #"senderId":self.senderId, #"mediaType":#"VIDEO"};
[newMessage setValue:messageItem];
}];
}
}
#end
What wrong with my code?
I am stuck with a problem on the mapView. I am really sorry to ask this question but I have searched for almost one day to look into this issue but I don't find a solution to fix it.
#interface MapViewController ()<CLLocationManagerDelegate, MKMapViewDelegate, UITextFieldDelegate, CheckInDelegate, NotificationsViewControllerDelegate, ReportVCDelegate, TutorialViewControllerDelegate> {
CLLocationManager *locationManager;
NSTimer *refreshTimer;
int rangeValue;
CheckInViewController *checkInVC;
TutorialViewController *tutorialVC1;
TutorialViewController *tutorialVC2;
UIImageView *imgAvatar;
NSArray *markers;
}
#property (weak, nonatomic) IBOutlet UIView *viewSearch;
#property (weak, nonatomic) IBOutlet RateView *viewRate;
#property (weak, nonatomic) IBOutlet UIView *viewBottom;
#property (weak, nonatomic) IBOutlet UILabel *lblUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtSearch;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *btnNotifications;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomSpace;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomHeight;
#property (weak, nonatomic) IBOutlet UIButton *btnBottom;
#property (weak, nonatomic) IBOutlet HandsawayMapView *mapView;
#property (weak, nonatomic) IBOutlet UIView *mapViewContainer;
#property (strong, nonatomic) MKPlacemark *searchMarker;
#property (strong, nonatomic) MKUserLocation *myMarker;
#property (weak, nonatomic) MapToolbarViewController *mapToolbar;
#property (strong, atomic) NSArray *allMapMarkers;
#property (strong, nonatomic) NSNumber *aggressionIdToCenter;
#end
#implementation MapViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// [[UserModel sharedModel] setUserHome:#(1)];
rangeValue = 300;
self.viewSearch.layer.masksToBounds = NO;
self.viewSearch.layer.shadowRadius = 0.5f;
self.viewSearch.layer.shadowColor = [UIColor blackColor].CGColor;
self.viewSearch.layer.shadowOffset = CGSizeMake(0.0f, 0.5f);
self.viewSearch.layer.shadowOpacity = 0.5f;
self.viewRate.starCount = 4;
self.viewRate.step = 1.0f;
self.viewRate.starNormalColor = UIColorFromRGB(0xD8D8D8);
self.viewRate.starFillColor = UIColorFromRGB(0xFF5B59);
self.viewRate.rating = 3.0f;
self.viewRate.starSize = 20.0f;
self.viewRate.padding = 8.0f;
locationManager = [[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization];
locationManager.delegate = self;
[DbHelper saveActivationWithNumer:#(1)];
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
}];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSNumber *agressionID = [[NSUserDefaults standardUserDefaults] valueForKey:#"aggression_id"];
if (agressionID && agressionID != 0)
{
self.aggressionIdToCenter = agressionID;
[[NSUserDefaults standardUserDefaults] setValue:0 forKey:#"aggression_id"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
if (self.aggressionIdToCenter != nil) {
[self centerOnAggressionWithId:self.aggressionIdToCenter];
self.aggressionIdToCenter = nil;
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[locationManager stopUpdatingLocation];
didSetLocation = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIView*)locationPin {
User *user = [DbHelper getCurrentUser];
UIImage *pin = [UIImage imageNamed:#"marker-person"];
if([user.isCurrent boolValue]) {
pin = [UIImage imageNamed:#"my-pin"];
}
UIImageView *pinImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 39, 48)];
[pinImageView setImage:pin];
UIView *markerContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 39, 48)];
[markerContainer addSubview:pinImageView];
imgAvatar = [[UIImageView alloc] initWithFrame:CGRectMake(4.5, 4.5, 30, 30)];
[imgAvatar setContentMode:UIViewContentModeScaleAspectFill];
imgAvatar.layer.cornerRadius = 15;
imgAvatar.clipsToBounds = YES;
[markerContainer addSubview:imgAvatar];
if([user.isPictureHidden boolValue]) {
[imgAvatar setImage:[user avatarPlaceholder]];
}
else {
[imgAvatar setImageWithURL:[NSURL URLWithString:user.pictureURL] placeholderImage:[user avatarPlaceholder]];
}
[pinImageView setBackgroundColor:[UIColor clearColor]];
[imgAvatar setBackgroundColor:[UIColor clearColor]];
[markerContainer setBackgroundColor:[UIColor clearColor]];
return markerContainer;
}
- (void)ckeckUserImage
{
User *user = [DbHelper getCurrentUser];
if([user.isPictureHidden boolValue]) {
[imgAvatar setImage:[user avatarPlaceholder]];
}
else {
[imgAvatar setImageWithURL:[NSURL URLWithString:user.pictureURL] placeholderImage:[user avatarPlaceholder]];
}
if (self.mapToolbar.currentUser)
{
[self.mapToolbar setCurrentUser];
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if([segue.identifier isEqualToString:#"PresentInfo"]) {
self.mapToolbar = segue.destinationViewController;
self.mapToolbar.height = self.bottomHeight;
self.mapToolbar.masterVC = self;
} else if ([segue.identifier isEqualToString:#"NotificationsSegue"] && [segue.destinationViewController isKindOfClass:[NotificationsViewController class]]) {
NotificationsViewController *destination = (NotificationsViewController *)segue.destinationViewController;
destination.delegate = self;
}
else if([segue.identifier isEqualToString:#"ActionSheetMap"]) {
self.VCactionSheetMap = segue.destinationViewController;
self.VCactionSheetMap.delegate = self.mapToolbar;
} else if ([segue.identifier isEqualToString:#"mapToReport"]) {
self.reportVC = (ReportVC *)segue.destinationViewController;
self.reportVC.delegate = self;
}
}
- (IBAction)onMenu:(id)sender {
[self.frostedViewController presentMenuViewController];
}
-(IBAction)onLocate:(id)sender {
self.txtSearch.text = #"";
[self.mapView removeAnnotation:self.searchMarker];
self.searchMarker = nil;
didSetLocation = NO;
}
- (IBAction)onCheckIn:(id)sender {
if([[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials2"]) {
self.btnCheckin.hidden = YES;
checkInVC = [self.storyboard instantiateViewControllerWithIdentifier:#"NewCheckin"];
checkInVC.delegate = self;
checkInVC.model = [[CheckInModel alloc] init];
if(_searchMarker != nil) {
checkInVC.model.longitude = (double) _searchMarker.coordinate.longitude;
checkInVC.model.latitude = (double) _searchMarker.coordinate.latitude;
}
else {
checkInVC.model.longitude = (double) locationManager.location.coordinate.longitude;
checkInVC.model.latitude = (double) locationManager.location.coordinate.latitude;
}
if([sender isKindOfClass:[NSNumber class]]) {
checkInVC.agressionId = sender;
}
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:checkInVC.view];
}
else {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(![[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials2"]) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.btnCheckin setAdjustsImageWhenHighlighted:NO];
[self.btnCheckin setUserInteractionEnabled:NO];
UIStoryboard *tutorials = [UIStoryboard storyboardWithName:#"Tutorial" bundle:nil];
tutorialVC2 = (TutorialViewController *)[tutorials instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"Tutorial%ld", (long)2]];
tutorialVC2.delegate = self;
[[tutorialVC2 view] setFrame:self.view.bounds];
[self.view insertSubview:[tutorialVC2 view] belowSubview:self.btnCheckin];
[[NSUserDefaults standardUserDefaults] setValue:#YES forKey:#"tutorials2"];
}
});
}
}
- (IBAction)onNotifications:(id)sender {
if([[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials1"]) {
[self performSegueWithIdentifier:#"NotificationsSegue" sender:nil];
}
else {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(![[NSUserDefaults standardUserDefaults] valueForKey:#"tutorials1"]) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
UIStoryboard *tutorials = [UIStoryboard storyboardWithName:#"Tutorial" bundle:nil];
tutorialVC1 = (TutorialViewController *)[tutorials instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"Tutorial%ld", (long)1]];
tutorialVC1.delegate = self;
[[tutorialVC1 view] setFrame:self.view.bounds];
[self.view addSubview:[tutorialVC1 view]];
[[NSUserDefaults standardUserDefaults] setValue:#YES forKey:#"tutorials1"];
}
});
});
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
[manager startUpdatingLocation];
}
BOOL didSetLocation;
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray<CLLocation *> *)locations {
if(locations.count > 0 ) {
CLLocation *aUserLocation = locations[0];
self.myMarker.coordinate = aUserLocation.coordinate;
// if(_myMarker == nil) {
// GMSMarker *marker = [[GMSMarker alloc] init];
// marker.iconView = [[DbHelper getCurrentUser] locationPin];
// marker.map = mapView_;
// _myMarker = marker;
// }
// _myMarker.position = aUserLocation.coordinate;
if(!didSetLocation) {
didSetLocation = YES;
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.01557113906538632;
span.longitudeDelta = 0.02284631241712987;
CLLocationCoordinate2D location;
location.latitude = aUserLocation.coordinate.latitude;
location.longitude = aUserLocation.coordinate.longitude;
region.span = span;
region.center = location;
[self.mapView setRegion:region animated:YES];
// [APICLIENT locateUserWithCoordinates:location
// completion:^(NSDictionary *result) {
//
// } error:^{
//
// }];
}
}
}
#pragma mark - Bottom bar
BOOL isBottomBarShown = YES;
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
// NSLog(#"longitured : %#, lattitude: %#", #(mapView.region.span.longitudeDelta), #(mapView.region.span.latitudeDelta));
[self hideBottomView];
[refreshTimer invalidate];
refreshTimer = [NSTimer scheduledTimerWithTimeInterval:0.8
target:self
selector:#selector(refreshMapMarkersWithCoordinates:)
userInfo:#{#"longitude" : #(mapView.region.center.longitude), #"latitude" : #(mapView.region.center.latitude), #"range" : #(rangeValue)}
repeats:NO];
}
- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if(![annotation isKindOfClass:[MKPlacemark class]]) {
MKAnnotationView * annotationView = [MKAnnotationView new];
if([annotation isKindOfClass:[MKUserLocation class]]) {
UIView *userView = [self locationPin];
[annotationView setFrame:userView.frame];
[annotationView addSubview:userView];
self.myMarker = annotation;
[self.mapView sendSubviewToBack:annotationView];
}
else {
annotationView.annotation = annotation;
Marker *dbmarker = ((MarkerAnnotation*)annotation).userData;
if(dbmarker.agression != nil) {
[annotationView setImage:[dbmarker markerImage]];
[self.mapView bringSubviewToFront:annotationView];
}
else if(dbmarker.user != nil) {
UIView *userView = [dbmarker userMarkerView];
[annotationView setFrame:userView.frame];
[annotationView addSubview:userView];
[self.mapView bringSubviewToFront:annotationView];
}
}
return annotationView;
}
return nil;
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
if(view.annotation != self.searchMarker && view.annotation != self.myMarker) {
if([view.annotation isKindOfClass:[MKUserLocation class]]) {
}
else {
[self selectMarker:((MarkerAnnotation*)view.annotation).userData];
}
}
else
{
if (view.annotation == self.myMarker)
{
[self.mapToolbar setCurrentUser];
}
[self showBottomView];
}
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
if(view.annotation != self.searchMarker && view.annotation != self.myMarker) {
if([view.annotation isKindOfClass:[MKUserLocation class]]) {
}
else {
[self hideBottomView];
}
}
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
[APICLIENT locateUserWithCoordinates:userLocation.location.coordinate
completion:^(NSDictionary *result) {
} error:^{
}];
}
#pragma mark - GMSMap delegate
//- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
// [self selectMarker:marker];
// return YES;
//}
- (void)selectMarker:(Marker *)marker {
Marker *dbMarker = marker;
if(dbMarker.agression != nil) {
[APICLIENT getAgressionWithId:dbMarker.agression.webID
completion:^(Marker *newmarker) {
[APICLIENT getUserById:[newmarker.user.webID stringValue]
completion:^(User *result) {
self.mapToolbar.marker = newmarker;
//[self showBottomView];
} error:^{
}];
} error:^{
}];
}
else {
[APICLIENT getUserById:[dbMarker.user.webID stringValue]
completion:^(User *result) {
self.mapToolbar.marker = dbMarker;
[self showBottomView];
} error:^{
}];
}
}
-(void)reloadMarkers {
[APICLIENT getMapMarkersAroundMeWithCoordinates:self.mapView.region.center
range:#(rangeValue)
completion:^(NSArray *result) {
[self updateDistance];
NSArray *oldAnnotations = [self.mapView.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF.class == %#", [MarkerAnnotation class]]];
oldAnnotations = [oldAnnotations valueForKey:#"userData"];
markers = [Marker MR_findAllWithPredicate:[NSPredicate predicateWithFormat:#"NOT (SELF IN %#)", oldAnnotations]];
//[self.mapView removeAnnotations:self.mapView.annotations];
NSMutableArray *allMapMarkersMutable = [[NSMutableArray alloc] init];
for(Marker *dbmarker in markers) {
MarkerAnnotation *marker = [[MarkerAnnotation alloc] init];
marker.coordinate = CLLocationCoordinate2DMake([dbmarker.latitude doubleValue], [dbmarker.longitude doubleValue]);
marker.userData = dbmarker;
[self.mapView addAnnotation:marker];
[allMapMarkersMutable addObject:marker];
}
self.allMapMarkers = [[allMapMarkersMutable copy] arrayByAddingObjectsFromArray:oldAnnotations];
if(_searchMarker != nil && ![self.mapView.annotations containsObject:_searchMarker]) {
[self.mapView addAnnotation:_searchMarker];
}
if(self.aggressionIdToCenter != nil) {
[self centerOnAggressionWithId:self.aggressionIdToCenter];
self.aggressionIdToCenter = nil;
}
} error:^{
}];
/*NSArray *oldAnnotations = [self.mapView.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF.class == %#", [MarkerAnnotation class]]];
oldAnnotations = [oldAnnotations valueForKey:#"userData"];
markers = [Marker MR_findAllWithPredicate:[NSPredicate predicateWithFormat:#"NOT (SELF IN %#)", oldAnnotations]];
// [self.mapView removeAnnotations:self.mapView.annotations];
NSMutableArray *allMapMarkersMutable = [[NSMutableArray alloc] init];
for(Marker *dbmarker in markers) {
MarkerAnnotation *marker = [[MarkerAnnotation alloc] init];
marker.coordinate = CLLocationCoordinate2DMake([dbmarker.latitude doubleValue], [dbmarker.longitude doubleValue]);
marker.userData = dbmarker;
[self.mapView addAnnotation:marker];
[allMapMarkersMutable addObject:marker];
}
self.allMapMarkers = [[allMapMarkersMutable copy] arrayByAddingObjectsFromArray:oldAnnotations];
if(_searchMarker != nil && ![self.mapView.annotations containsObject:_searchMarker]) {
[self.mapView addAnnotation:_searchMarker];
}
if(self.aggressionIdToCenter != nil) {
[self centerOnAggressionWithId:self.aggressionIdToCenter];
self.aggressionIdToCenter = nil;
}*/
}
//-(void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
// [self hideBottomView];
//}
#pragma mark - UITextFieldDelegate and place search
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.view endEditing:YES];
MKCoordinateRegion newRegion;
newRegion.center.latitude = locationManager.location.coordinate.latitude;
newRegion.center.longitude = locationManager.location.coordinate.longitude;
// Setup the area spanned by the map region:
// We use the delta values to indicate the desired zoom level of the map,
// (smaller delta values corresponding to a higher zoom level).
// The numbers used here correspond to a roughly 8 mi
// diameter area.
//
newRegion.span.latitudeDelta = 0.112872;
newRegion.span.longitudeDelta = 0.109863;
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = textField.text;
request.region = newRegion;
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error) {
if (error != nil) {
// NSString *errorStr = [[error userInfo] valueForKey:NSLocalizedDescriptionKey];
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Could not find places"
// message:errorStr
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil];
// [alert show];
} else {
NSArray<MKMapItem *> *mapItems = [response mapItems];
if(mapItems.count > 0) {
MKCoordinateRegion boundingRegion = response.boundingRegion;
MKMapItem *item = mapItems[0];
self.searchMarker = item.placemark;
[self.mapView addAnnotation:item.placemark];
[self.mapView setRegion:boundingRegion animated:YES];
}
}
};
[localSearch startWithCompletionHandler:completionHandler];
double radians(double degrees) {
return degrees * M_PI / 180.0;
}
double degrees(double radians) {
return radians * 180.0 / M_PI;
}
const CLLocationDegrees kLatLonEarthRadius = 6371.0;
CLLocationCoordinate2D LatLonDestPoint(CLLocationCoordinate2D origin, double bearing, CLLocationDistance distance) {
double brng = radians(bearing);
double lat1 = radians(origin.latitude);
double lon1 = radians(origin.longitude);
CLLocationDegrees lat2 = asin(sin(lat1) * cos(distance / kLatLonEarthRadius) +
cos(lat1) * sin(distance / kLatLonEarthRadius) * cos(brng));
CLLocationDegrees lon2 = lon1 + atan2(sin(brng) * sinf(distance / kLatLonEarthRadius) * cos(lat1),
cosf(distance / kLatLonEarthRadius) - sin(lat1) * sin(lat2));
lon2 = fmod(lon2 + M_PI, 2.0 * M_PI) - M_PI;
CLLocationCoordinate2D coordinate;
if (! (isnan(lat2) || isnan(lon2))) {
coordinate.latitude = degrees(lat2);
coordinate.longitude = degrees(lon2);
}
return coordinate;
}
#pragma mark - CheckInDelegate
- (void)willRemoveCheckinView {
[[UIApplication sharedApplication] setStatusBarHidden:NO
withAnimation:UIStatusBarAnimationSlide];
[self.navigationController setNavigationBarHidden:NO
animated:YES];
}
The problem is you are adding marker in MKLocalSearchCompletionHandler, so remove below line from MKLocalSearchCompletionHandler will solved your issue.
[self.mapView addAnnotation:item.placemark];
You can remove all annotation pins from MKMapView by using following code
for (int i =0; i < [_mapView.annotations count]; i++) {
if ([[_mapView.annotations objectAtIndex:i] isKindOfClass:[YOURANNOTATIONCLASS class]]) {
[_mapView removeAnnotation:[_mapView.annotations objectAtIndex:i]];
}
}
If you want to remove Annotation while search then remove bellow code in textFieldShouldReturn method.
Find method:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
}
Then Comment or Remove bellow code
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = textField.text;
request.region = newRegion;
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error) {
if (error != nil) {
// NSString *errorStr = [[error userInfo] valueForKey:NSLocalizedDescriptionKey];
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Could not find places"
// message:errorStr
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil];
// [alert show];
} else {
NSArray<MKMapItem *> *mapItems = [response mapItems];
if(mapItems.count > 0) {
MKCoordinateRegion boundingRegion = response.boundingRegion;
MKMapItem *item = mapItems[0];
self.searchMarker = item.placemark;
[self.mapView addAnnotation:item.placemark];
[self.mapView setRegion:boundingRegion animated:YES];
}
}
};
Hope it will help you
Hi everyone iam new in objective c, now i try to create the app like "What's the word". I find this tutorial and lerned it as well as i can. But i have some problems. I want when i click on buttons the currentTitle replace the lable in placesView. Button click method in LettersView.m named as "displayChar". I have success in getting currentTitle but now i don't know how to pass it to GameController and paste text on "places".
I will be grateful for any help!
Here is my code
LettersView.h
#import <UIKit/UIKit.h>
#class LettersView;
#protocol LetterClickDelegateProtocol <NSObject>
-(void)letterView:(LettersView*)letterView addChar:(NSString *)addChar;
#end
#interface LettersView : UIImageView
#property (strong, nonatomic, readonly) NSString* letter;
#property (assign, nonatomic) BOOL isMatched;
#property (strong, nonatomic) NSString *clickLetter;
#property (weak, nonatomic) id<LetterClickDelegateProtocol> clickDelegate;
#property (strong, nonatomic) UIButton *lblChar;
-(instancetype)initWithLetter:(NSString*)letter andSideLength:(float)sideLength;
#end
LettersView.m
#import "LettersView.h"
#import "config.h"
#implementation LettersView{
NSInteger _xOffset, _yOffset;
}
- (id)initWithFrame:(CGRect)frame
{
NSAssert(NO, #"Use initWithLetter:andSideLength instead");
return nil;
}
-(instancetype)initWithLetter:(NSString*)letter andSideLength:(float)sideLength
{
//the letter background
UIImage* img = [UIImage imageNamed:#"btn_letter#2x.png"];
//create a new object
self = [super initWithImage:img];
if (self != nil) {
//resize the letters
float scale = sideLength/img.size.width;
self.frame = CGRectMake(0,0,img.size.width*scale, img.size.height*scale);
UIButton *lblChar = [[UIButton alloc] initWithFrame:self.bounds];
lblChar.tintColor = [UIColor blackColor];
lblChar.backgroundColor = [UIColor clearColor];
[lblChar setTitle:letter forState:UIControlStateNormal];
[lblChar addTarget:self action:#selector(displaychar:)forControlEvents:UIControlEventTouchUpInside];
[self addSubview:lblChar];
self.isMatched = NO;
_letter = letter;
self.userInteractionEnabled = YES;
}
return self;
}
-(void)displayChar:(id)sender {
UIButton *lblChar = (UIButton *)sender;
NSLog(#" The button's title is %#.", lblChar.currentTitle);
_clickLetter = lblChar.currentTitle;
if (self.clickDelegate) {
[self.clickDelegate letterView:self addChar:lblChar.currentTitle];
}
NSLog(#"hu %#", _clickLetter);
}
PlacesView.h
// PlacesView.m
#import "PlacesView.h"
#import "config.h"
#implementation PlacesView
-(id)initWithFrame:(CGRect)frame {
NSAssert(NO, #"Use initwithletter");
return nil;
}
-(instancetype)initWithLetter:(NSString *)letter andSideLength:(float)sideLength
{
UIImage *img = [UIImage imageNamed:#"btn_input#2x.png"];
self = [super initWithImage: img];
if (self != nil) {
self.isMatched = NO;
float scale = sideLength/img.size.width;
self.frame = CGRectMake(0, 0, img.size.width*scale, img.size.height*scale);
//bullshit time
_fieldForLetter = [[UILabel alloc] initWithFrame:self.bounds];
_fieldForLetter.textAlignment = NSTextAlignmentCenter;
_fieldForLetter.textColor = [UIColor blackColor];
_fieldForLetter.backgroundColor = [UIColor clearColor];
_fieldForLetter.text = #"*"; // if button pressed button title placed here.
[self addSubview:_fieldForLetter];
_letter = letter;
}
return self;
}
#end
GameController.m
#import "GameController.h"
#import "config.h"
#import "LettersView.h"
#import "PlacesView.h"
#import "AppDelegate.h"
#implementation GameController {
//tile lists
NSMutableArray* _letters;
NSMutableArray* _places;
}
-(instancetype)init {
self = [super init];
if (self != nil) {
self.points = [[PointsController alloc] init];
self.audioController = [[AudioController alloc] init];
[self.audioController preloadAudioEffects: kAudioEffectFiles];
}
return self;
}
-(void)dealRandomWord {
NSAssert(self.level.words, #"Level not loaded");
// random word from plist
NSInteger randomIndex = arc4random()%[self.level.words count];
NSArray* anaPair = self.level.words[ randomIndex ];
NSString* word1 = anaPair[1]; // answer
NSString* word2 = anaPair[2]; // some letters
_helpstr = anaPair[3]; // helper
NSLog(#"qweqweq %# %#" , word1 , word2);
NSInteger word1len = [word1 length];
NSInteger word2len = [word2 length];
NSLog(#"phrase1[%li]: %#", (long)word1len, word1);
NSLog(#"phrase2[%li]: %#", (long)word2len, word2);
//calculate the letter size
float letterSide = ceilf( kScreenWidth*0.9 / (float)MAX(word1len, word2len) ) - kTileMargin;
//get the left margin for first letter
float xOffset = (kScreenWidth - MAX(word1len, word2len) * (letterSide + kTileMargin))/2;
//adjust for letter center
xOffset += letterSide/2;
float yOffset = 1.5* letterSide;
// init places list
_places = [NSMutableArray arrayWithCapacity: word1len];
// create places
for (NSInteger i = 0; i<word1len; i++){
NSString *letter = [word1 substringWithRange:NSMakeRange(i, 1)];
if (![letter isEqualToString:#" "]) {
PlacesView* place = [[PlacesView alloc] initWithLetter:letter andSideLength:letterSide];
place.center = CGPointMake(xOffset + i*(letterSide + kTileMargin), kScreenHeight/4);
[self.gameView addSubview:place];
[_places addObject: place];
}
}
//init letters list
_letters = [NSMutableArray arrayWithCapacity: word2len];
//create letter
for (NSInteger i=0;i<word2len;i++) {
NSString* letter = [word2 substringWithRange:NSMakeRange(i, 1)];
if (![letter isEqualToString:#" "]) {
LettersView* letv = [[LettersView alloc] initWithLetter:letter andSideLength:letterSide];
letv.center = CGPointMake(xOffset + i * (letterSide + kTileMargin), kScreenHeight); // "/3*4"
if (i > 6) {
letv.center = CGPointMake(-5.15 * xOffset + i * (letterSide + kTileMargin), kScreenHeight + yOffset); // "/3*4"
}
letv.clickDelegate = self;
[self.gameView addSubview:letv];
[_letters addObject: letter];
}
}
}
-(void)letterView:(LettersView *)letterView addChar:(NSString *)addChar
{
PlacesView* placesView = nil;
for (PlacesView* pl in _places) {
//if (CGRectContainsPoint(pl.frame, pt)) {
if () {
//placesView = pl;
placesView.fieldForLetter.text = letterView.lblChar.currentTitle;
break;
}
}
//1 check if target was found
if (placesView!=nil) {
//2 check if letter matches
if ([placesView.letter isEqualToString: letterView.letter]) {
[self placeLetter:letterView atTarget:placesView];
[self.audioController playEffect: kSoundLetterTap];
self.points.points += self.level.coinsPerLvl; //ne nado tak
NSLog(#"Current points %d" , self.points.points);
[self checkForSuccess];
} else {
[self.audioController playEffect:kSoundFail];
[self addAlert:#"ne success" andMessage:#"You lose!" andButton:#"eshe cyka"];
}
}
}
-(void)placeLetter:(LettersView*)letterView atTarget:(PlacesView*)placeView {
placeView.isMatched = YES;
letterView.isMatched = YES;
letterView.userInteractionEnabled = NO;
}
-(void)checkForSuccess {
for (PlacesView* p in _places) {
//no success, bail out
if (p.isMatched==NO) return;
}
NSLog(#"ya!");
[self addAlert:#"Success" andMessage:#"You win!" andButton:#"eshe cyka"];
[self.audioController playEffect:kSoundSuccess];
}
-(void)addAlert: (NSString *)addTitle andMessage: (NSString *)alertMessage andButton: (NSString *)alertButton {
dispatch_async(dispatch_get_main_queue(), ^{
UIWindow* window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
window.rootViewController = [UIViewController new];
window.windowLevel = UIWindowLevelAlert + 1;
UIAlertController *alert = [UIAlertController alertControllerWithTitle: addTitle message:alertMessage preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction= [UIAlertAction actionWithTitle:alertButton style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
window.hidden = YES;
}];
[alert addAction:defaultAction];
[window makeKeyAndVisible];
[window.rootViewController presentViewController:alert animated:YES completion:nil];
});
}
#end
Your GameController needs to keep a reference to PlacesView. It can also assign the action into LettersView so when the button in LettersView is pressed, the GameController will fetch it and perform an action in PlacesView. GameController is what both the other classes have in common, so it can handle any actions between them.
Another option is to use NSNotificationCenter and post a message in LettersView when the button is pressed, and listen for it in PlacesView.
Yet anther way is using a delegates where GameController makes sure that PlacesView is set as the delegate. When LettersView's button is pressed, it will call the delegate method which PlacesView listens to.
I'd go with first option.
I can't forever read and try to understand the whole codes of MWPhotoBrowser's Example Project. I can't figure out where does this project get the Photos data. I've been trying to understand the project since last week.
So here's the thing, I'm trying to make an app that uses this MWPhotoBrowser (https://github.com/mwaterfall/MWPhotoBrowser/blob/master/README.md) open source project/library. An app that can browse all the albums in my phone but using the MWPhotoBrowser.
In the example proejct of the MWPhotoBrowser, there's a sample code how to browse the local photos of the phone. There are lots of examples but I managed to delete some of them and retain just the last one option. - Library Photos and Videos (Case:9 if you're going to look at the code).
What I have done so far:
Implement the open source project (Gallery Viewer App) from developer.apple.com - successfully implemented, but I'm not satisfied because MWPhotoBrowser is better and cooler.
Edit the Sample Project of MWPhotoBrowser.
CODE:
//
// Menu.m
// MWPhotoBrowser
//
// Created by Michael Waterfall on 21/10/2010.
// Copyright 2010 d3i. All rights reserved.
//
#import <Photos/Photos.h>
#import "Menu.h"
#import "SDImageCache.h"
#import "MWCommon.h"
#implementation Menu
#pragma mark -
#pragma mark View
- (void)viewDidLoad {
[super viewDidLoad];
// Test toolbar hiding
// [self setToolbarItems: #[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil]]];
// [[self navigationController] setToolbarHidden:NO animated:NO];
NSLog(#"view did load....");
self.title = #"MWPhotoBrowser";
// Clear cache for testing
[[SDImageCache sharedImageCache] clearDisk];
[[SDImageCache sharedImageCache] clearMemory];
[self loadAssets];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
// self.navigationController.navigationBar.translucent = NO;
// [self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// [self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger rows = 1;
#synchronized(_assets) {
if (_assets.count) rows++;
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.accessoryType = _segmentedControl.selectedSegmentIndex == 0 ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
// Configure
switch (indexPath.row) {
case 0: {
cell.textLabel.text = #"Library photos and videos";
cell.detailTextLabel.text = #"media from device library";
break;
}
default: break;
}
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Did Select...");
// Browser
NSMutableArray *photos = [[NSMutableArray alloc] init];
NSMutableArray *thumbs = [[NSMutableArray alloc] init];
MWPhoto *photo, *thumb;
BOOL displayActionButton = YES;
BOOL displaySelectionButtons = NO;
BOOL displayNavArrows = NO;
BOOL enableGrid = YES;
BOOL startOnGrid = NO;
BOOL autoPlayOnAppear = NO;
//#synchronized(_assets) {
NSMutableArray *copy = [_assets copy];
if (NSClassFromString(#"PHAsset")) {
// Photos library
UIScreen *screen = [UIScreen mainScreen];
CGFloat scale = screen.scale;
// Sizing is very rough... more thought required in a real implementation
CGFloat imageSize = MAX(screen.bounds.size.width, screen.bounds.size.height) * 1.5;
CGSize imageTargetSize = CGSizeMake(imageSize * scale, imageSize * scale);
CGSize thumbTargetSize = CGSizeMake(imageSize / 3.0 * scale, imageSize / 3.0 * scale);
for (PHAsset *asset in copy) {
[photos addObject:[MWPhoto photoWithAsset:asset targetSize:imageTargetSize]];
[thumbs addObject:[MWPhoto photoWithAsset:asset targetSize:thumbTargetSize]];
}
}
else {
// Assets library
for (ALAsset *asset in copy) {
MWPhoto *photo = [MWPhoto photoWithURL:asset.defaultRepresentation.url];
[photos addObject:photo];
MWPhoto *thumb = [MWPhoto photoWithImage:[UIImage imageWithCGImage:asset.thumbnail]];
[thumbs addObject:thumb];
if ([asset valueForProperty:ALAssetPropertyType] == ALAssetTypeVideo) {
photo.videoURL = asset.defaultRepresentation.url;
thumb.isVideo = true;
}
}
}
//}
self.photos = photos;
self.thumbs = thumbs;
// Create browser
MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = displayActionButton;
browser.displayNavArrows = displayNavArrows;
browser.displaySelectionButtons = displaySelectionButtons;
browser.alwaysShowControls = displaySelectionButtons;
browser.zoomPhotosToFill = YES;
browser.enableGrid = enableGrid;
browser.startOnGrid = startOnGrid;
browser.enableSwipeToDismiss = NO;
browser.autoPlayOnAppear = autoPlayOnAppear;
[browser setCurrentPhotoIndex:0];
// Test custom selection images
// browser.customImageSelectedIconName = #"ImageSelected.png";
// browser.customImageSelectedSmallIconName = #"ImageSelectedSmall.png";
// Reset selections
if (displaySelectionButtons) {
_selections = [NSMutableArray new];
for (int i = 0; i < photos.count; i++) {
[_selections addObject:[NSNumber numberWithBool:NO]];
}
}
// Show
[self.navigationController pushViewController:browser animated:YES];
}
#pragma mark - MWPhotoBrowserDelegate
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
if (index < _thumbs.count)
return [_thumbs objectAtIndex:index];
return nil;
}
//- (MWCaptionView *)photoBrowser:(MWPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index {
// MWPhoto *photo = [self.photos objectAtIndex:index];
// MWCaptionView *captionView = [[MWCaptionView alloc] initWithPhoto:photo];
// return [captionView autorelease];
//}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser actionButtonPressedForPhotoAtIndex:(NSUInteger)index {
NSLog(#"ACTION!");
}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser didDisplayPhotoAtIndex:(NSUInteger)index {
NSLog(#"Did start viewing photo at index %lu", (unsigned long)index);
}
- (BOOL)photoBrowser:(MWPhotoBrowser *)photoBrowser isPhotoSelectedAtIndex:(NSUInteger)index {
return [[_selections objectAtIndex:index] boolValue];
}
//- (NSString *)photoBrowser:(MWPhotoBrowser *)photoBrowser titleForPhotoAtIndex:(NSUInteger)index {
// return [NSString stringWithFormat:#"Photo %lu", (unsigned long)index+1];
//}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index selectedChanged:(BOOL)selected {
[_selections replaceObjectAtIndex:index withObject:[NSNumber numberWithBool:selected]];
NSLog(#"Photo at index %lu selected %#", (unsigned long)index, selected ? #"YES" : #"NO");
}
//////////////
#pragma mark - Load Assets
- (void)loadAssets {
if (NSClassFromString(#"PHAsset")) {
// Check library permissions
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
[self performLoadAssets];
}
}];
} else if (status == PHAuthorizationStatusAuthorized) {
[self performLoadAssets];
}
} else {
// Assets library
[self performLoadAssets];
}
}
- (void)performLoadAssets {
// Initialise
_assets = [NSMutableArray new];
// Load
if (NSClassFromString(#"PHAsset")) {
// Photos library iOS >= 8
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
PHFetchOptions *options = [PHFetchOptions new];
options.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:NO]];
PHFetchResult *fetchResults = [PHAsset fetchAssetsWithOptions:options];
[fetchResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_assets addObject:obj];
}];
if (fetchResults.count > 0) {
// [self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
});
} else {
// Assets Library iOS < 8
_ALAssetsLibrary = [[ALAssetsLibrary alloc] init];
// Run in the background as it takes a while to get all assets from the library
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
NSMutableArray *assetURLDictionaries = [[NSMutableArray alloc] init];
// Process assets
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result != nil) {
NSString *assetType = [result valueForProperty:ALAssetPropertyType];
if ([assetType isEqualToString:ALAssetTypePhoto] || [assetType isEqualToString:ALAssetTypeVideo]) {
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url = result.defaultRepresentation.url;
[_ALAssetsLibrary assetForURL:url
resultBlock:^(ALAsset *asset) {
if (asset) {
#synchronized(_assets) {
[_assets addObject:asset];
if (_assets.count == 1) {
// Added first asset so reload data
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
}
}
}
failureBlock:^(NSError *error){
NSLog(#"operation was not successfull!");
}];
}
}
};
// Process groups
void (^ assetGroupEnumerator) (ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if (group != nil) {
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:assetEnumerator];
[assetGroups addObject:group];
}
};
// Process!
[_ALAssetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {
NSLog(#"There is an error");
}];
});
}
}
#end
Next, I tried to make a ViewController inside the Storyboard of the sample project, disconnected the connection between the navigation controller and the Table View controller. I Connected the Navigation Controller to ViewController. I then assigned my newly made class named: MainViewController.m to ViewController in the storyboard.
I copied all the codes, or rather, copy all the implementation of codes in the Main.m (the class connected to Table View of the sample project), to my MainViewController.m. So here's the code of mine so far:
//
// MainViewController.m
// MWPhotoBrowser
//
// Created by Glenn on 9/28/15.
// Copyright (
c) 2015 Michael Waterfall. All rights reserved.
//
#import "MainViewController.h"
#import <Photos/Photos.h>
// #import "Menu.h"
#import "SDImageCache.h"
#import "MWCommon.h"
#interface MainViewController ()
{
MWPhotoBrowser *browser;
}
#end
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self mwSetup];
self.title = #"MWPhotoBrowser";
// Clear cache for testing
[[SDImageCache sharedImageCache] clearDisk];
[[SDImageCache sharedImageCache] clearMemory];
[self loadAssets];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
// self.navigationController.navigationBar.translucent = NO;
// [self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// [self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
- (void)mwSetup
{
NSLog(#"Did Select...");
// Browser
NSMutableArray *photos = [[NSMutableArray alloc] init];
NSMutableArray *thumbs = [[NSMutableArray alloc] init];
MWPhoto *photo, *thumb;
BOOL displayActionButton = YES;
BOOL displaySelectionButtons = NO;
BOOL displayNavArrows = NO;
BOOL enableGrid = YES;
BOOL startOnGrid = NO;
BOOL autoPlayOnAppear = NO;
//#synchronized(_assets) {
NSMutableArray *copy = [_assets copy];
if (NSClassFromString(#"PHAsset")) {
// Photos library
UIScreen *screen = [UIScreen mainScreen];
CGFloat scale = screen.scale;
// Sizing is very rough... more thought required in a real implementation
CGFloat imageSize = MAX(screen.bounds.size.width, screen.bounds.size.height) * 1.5;
CGSize imageTargetSize = CGSizeMake(imageSize * scale, imageSize * scale);
CGSize thumbTargetSize = CGSizeMake(imageSize / 3.0 * scale, imageSize / 3.0 * scale);
for (PHAsset *asset in copy) {
[photos addObject:[MWPhoto photoWithAsset:asset targetSize:imageTargetSize]];
[thumbs addObject:[MWPhoto photoWithAsset:asset targetSize:thumbTargetSize]];
}
}
else {
// Assets library
for (ALAsset *asset in copy) {
MWPhoto *photo = [MWPhoto photoWithURL:asset.defaultRepresentation.url];
[photos addObject:photo];
MWPhoto *thumb = [MWPhoto photoWithImage:[UIImage imageWithCGImage:asset.thumbnail]];
[thumbs addObject:thumb];
if ([asset valueForProperty:ALAssetPropertyType] == ALAssetTypeVideo) {
photo.videoURL = asset.defaultRepresentation.url;
thumb.isVideo = true;
}
}
}
//}
self.photos = photos;
self.thumbs = thumbs;
// Create browser
browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = displayActionButton;
browser.displayNavArrows = displayNavArrows;
browser.displaySelectionButtons = displaySelectionButtons;
browser.alwaysShowControls = displaySelectionButtons;
browser.zoomPhotosToFill = YES;
browser.enableGrid = enableGrid;
browser.startOnGrid = startOnGrid;
browser.enableSwipeToDismiss = NO;
browser.autoPlayOnAppear = autoPlayOnAppear;
[browser setCurrentPhotoIndex:0];
// Test custom selection images
// browser.customImageSelectedIconName = #"ImageSelected.png";
// browser.customImageSelectedSmallIconName = #"ImageSelectedSmall.png";
// Reset selections
if (displaySelectionButtons) {
_selections = [NSMutableArray new];
for (int i = 0; i < photos.count; i++) {
[_selections addObject:[NSNumber numberWithBool:NO]];
}
}
// Show
[self.navigationController pushViewController:browser animated:YES];
//[self.view addSubview:browser.view];
}
#pragma mark - MWPhotoBrowserDelegate
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
if (index < _thumbs.count)
return [_thumbs objectAtIndex:index];
return nil;
}
//- (MWCaptionView *)photoBrowser:(MWPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index {
// MWPhoto *photo = [self.photos objectAtIndex:index];
// MWCaptionView *captionView = [[MWCaptionView alloc] initWithPhoto:photo];
// return [captionView autorelease];
//}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser actionButtonPressedForPhotoAtIndex:(NSUInteger)index {
NSLog(#"ACTION!");
}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser didDisplayPhotoAtIndex:(NSUInteger)index {
NSLog(#"Did start viewing photo at index %lu", (unsigned long)index);
}
- (BOOL)photoBrowser:(MWPhotoBrowser *)photoBrowser isPhotoSelectedAtIndex:(NSUInteger)index {
return [[_selections objectAtIndex:index] boolValue];
}
//- (NSString *)photoBrowser:(MWPhotoBrowser *)photoBrowser titleForPhotoAtIndex:(NSUInteger)index {
// return [NSString stringWithFormat:#"Photo %lu", (unsigned long)index+1];
//}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index selectedChanged:(BOOL)selected {
[_selections replaceObjectAtIndex:index withObject:[NSNumber numberWithBool:selected]];
NSLog(#"Photo at index %lu selected %#", (unsigned long)index, selected ? #"YES" : #"NO");
}
#pragma mark - Load Assets
- (void)loadAssets {
if (NSClassFromString(#"PHAsset")) {
// Check library permissions
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
[self performLoadAssets];
}
}];
} else if (status == PHAuthorizationStatusAuthorized) {
[self performLoadAssets];
}
} else {
// Assets library
[self performLoadAssets];
}
}
- (void)performLoadAssets {
// Initialise
_assets = [NSMutableArray new];
// Load
if (NSClassFromString(#"PHAsset")) {
// Photos library iOS >= 8
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
PHFetchOptions *options = [PHFetchOptions new];
options.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:NO]];
PHFetchResult *fetchResults = [PHAsset fetchAssetsWithOptions:options];
[fetchResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_assets addObject:obj];
}];
if (fetchResults.count > 0) {
[browser reloadData]; }
});
} else {
// Assets Library iOS < 8
_ALAssetsLibrary = [[ALAssetsLibrary alloc] init];
// Run in the background as it takes a while to get all assets from the library
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
NSMutableArray *assetURLDictionaries = [[NSMutableArray alloc] init];
// Process assets
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result != nil) {
NSString *assetType = [result valueForProperty:ALAssetPropertyType];
if ([assetType isEqualToString:ALAssetTypePhoto] || [assetType isEqualToString:ALAssetTypeVideo]) {
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url = result.defaultRepresentation.url;
[_ALAssetsLibrary assetForURL:url
resultBlock:^(ALAsset *asset) {
if (asset) {
#synchronized(_assets) {
[_assets addObject:asset];
if (_assets.count == 1) {
// Added first asset so reload data
[browser reloadData];
}
}
}
}
failureBlock:^(NSError *error){
NSLog(#"operation was not successfull!");
}];
}
}
};
// Process groups
void (^ assetGroupEnumerator) (ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if (group != nil) {
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:assetEnumerator];
[assetGroups addObject:group];
}
};
// Process!
[_ALAssetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {
NSLog(#"There is an error");
}];
});
}
}
#end
Please help. And can someone help me edit the format of my 2nd code? Thanks.
Okay, so I got it working. Basically, the MWPhotoBrowser needs a first view controller before loading itself.
For instance, in the sample project, the first screen is the Table View. Then you will select between the 9 rows, after that, the MWPhotoBrowser viewcontroller will be showed.
In my implementation, I just made a first view controller, and then added a button. When you click the button, the MWPhotoBrowser will be showed.
So that's how MWPhotoBrowser works. It doesn't load the photos and videos if you push the MWPhotoBrowser inside the ViewWillAppear, ViewDidLoad, ViewDidAppear.
Now, I have to learn or know how to load videos and photos from different album.
I have the following code using quickblox.
Unfortunately, when I accessthe view controller, I get an "unAuthorized" error from quickblox API.
What am I doing wrong?
#import "QChatViewController.h"
#include "ChatMessageTableViewCell.h"
#interface QChatViewController ()
#end
#implementation QChatViewController
#synthesize opponent;
#synthesize currentRoom;
#synthesize messages;
#synthesize toolBar;
#synthesize sendMessageField;
#synthesize sendMessageButton;
#synthesize tableView;
#pragma mark -
#pragma mark View controller's lifecycle
- (id) initWithStartup: (NSDictionary *) _startup investor: (NSDictionary *) _investor chat_id: (NSInteger) _chat_id chat_name: (NSString *) _name
{
self = [self initWithNibName: #"QChatViewController" bundle: nil];
if(self)
{
startup = _startup;
investor = _investor;
startup_id = 0;
investor_id = 0;
if ([startup objectForKey: #"id"] &&
[startup objectForKey: #"id"] != (id)[NSNull null])
{
startup_id = [[startup objectForKey: #"id"] intValue];
}
if ([investor objectForKey: #"id"] &&
[investor objectForKey: #"id"] != (id)[NSNull null])
{
investor_id = [[investor objectForKey: #"id"] intValue];
}
past = 0;
chat_id = _chat_id;
self.title = _name;
self.title = #"Chat";
UIButton * button4 = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage * btnImage = [UIImage imageNamed: #"chatrightbtn.png"];
[button4 setFrame:CGRectMake(-90.0f, 0.0f, btnImage.size.width, btnImage.size.height)];
[button4 addTarget:self action:#selector(showSheet:) forControlEvents:UIControlEventTouchUpInside];
[button4 setImage: btnImage forState:UIControlStateNormal];
UIBarButtonItem *random1 = [[UIBarButtonItem alloc] initWithCustomView:button4];
self.navigationItem.rightBarButtonItem = random1;
self.navigationItem.leftBarButtonItem.title = #"";
}
return self;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
QBASessionCreationRequest *extendedAuthRequest = [QBASessionCreationRequest request];
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"jerry";
[QBAuth createSessionWithExtendedRequest:extendedAuthRequest delegate:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBarHidden = NO;
if(chat_id >= 1) {
NSString * roomName = [NSString stringWithFormat: #"%d", chat_id];
[[QBChat instance] createOrJoinRoomWithName: roomName membersOnly:YES persistent:NO];
}
messages = [[NSMutableArray alloc] init];
}
-(void) chatDidLogin{
// You have successfully signed in to QuickBlox Chat
}
- (void)completedWithResult:(Result *)result{
// Create session result
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// You have successfully created the session
QBAAuthSessionCreationResult *res = (QBAAuthSessionCreationResult *)result;
// Sign In to QuickBlox Chat
QBUUser *currentUser = [QBUUser user];
currentUser.ID = res.session.userID; // your current user's ID
currentUser.password = #"jerry"; // your current user's password
// set Chat delegate
[QBChat instance].delegate = self;
// login to Chat
[[QBChat instance] loginWithUser:currentUser];
}
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// leave room
if(self.currentRoom){
if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
// back button was pressed.
[[QBChat instance] leaveRoom:self.currentRoom];
[[DataManager shared].rooms removeObject:self.currentRoom];
}
}
}
- (void)viewDidUnload{
[self setToolBar:nil];
[self setSendMessageField:nil];
[self setSendMessageButton:nil];
[self setTableView:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
}
- (IBAction)sendMessage:(id)sender {
if(self.sendMessageField.text.length == 0){
return;
}
if(chat_id == 0)
{
NSString * sid = [NSString stringWithFormat: #"%d", startup_id];
NSString * iid = [NSString stringWithFormat: #"%d", investor_id];
NSString * pasts = [NSString stringWithFormat: #"%d", past];
NSString * chat_ids = [NSString stringWithFormat: #"%d", chat_id];
NSString * path_str = [NSString stringWithFormat: #"chats/?format=json"];
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:
sid, #"startup",
iid, #"investor",
pasts, #"past",
chat_ids, #"conversation_id",
#"avv7ejtaegxxk2wzgnymsj8xtm2tk9s4xgp6854r6dqn8bk6jjwux4g9dh9b", #"apikey",
nil];
[[API sharedInstance] postcommandWithParams:params
path: path_str
onCompletion:^(NSDictionary *json)
{
if(chat_id == 0)
{
if ([json objectForKey: #"id"] &&
[json objectForKey: #"id"] != (id)[NSNull null])
{
chat_id = [[json objectForKey: #"id"] intValue];
if(chat_id >= 1) {
NSString * roomName = [NSString stringWithFormat: #"%d", chat_id];
[[QBChat instance] createOrJoinRoomWithName: roomName membersOnly:YES persistent:NO];
}
[[QBChat instance] sendMessage:self.sendMessageField.text toRoom:self.currentRoom];
// reload table
[self.tableView reloadData];
// hide keyboard & clean text field
[self.sendMessageField resignFirstResponder];
[self.sendMessageField setText:nil];
}
}
}];
}
else
{
[[QBChat instance] sendMessage:self.sendMessageField.text toRoom:self.currentRoom];
// reload table
[self.tableView reloadData];
// hide keyboard & clean text field
[self.sendMessageField resignFirstResponder];
[self.sendMessageField setText:nil];
}
}
-(void)keyboardShow{
CGRect rectFild = self.sendMessageField.frame;
rectFild.origin.y -= 215;
CGRect rectButton = self.sendMessageButton.frame;
rectButton.origin.y -= 215;
[UIView animateWithDuration:0.25f
animations:^{
[self.sendMessageField setFrame:rectFild];
[self.sendMessageButton setFrame:rectButton];
}
];
}
-(void)keyboardHide{
CGRect rectFild = self.sendMessageField.frame;
rectFild.origin.y += 215;
CGRect rectButton = self.sendMessageButton.frame;
rectButton.origin.y += 215;
[UIView animateWithDuration:0.25f
animations:^{
[self.sendMessageField setFrame:rectFild];
[self.sendMessageButton setFrame:rectButton];
}
];
}
#pragma mark -
#pragma mark TextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[self keyboardShow];
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
[self keyboardHide];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField setText:nil];
[textField resignFirstResponder];
return YES;
}
#pragma mark -
#pragma mark TableViewDataSource & TableViewDelegate
static CGFloat padding = 20.0;
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MessageCellIdentifier";
// Create cell
ChatMessageTableViewCell *cell = (ChatMessageTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ChatMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.userInteractionEnabled = NO;
// Message
QBChatMessage *messageBody = [messages objectAtIndex:[indexPath row]];
// set message's text
NSString *message = [messageBody text];
cell.message.text = message;
// message's datetime
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat: #"yyyy-mm-dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"..."]];
NSString *time = [formatter stringFromDate:messageBody.datetime];
CGSize textSize = { 260.0, 10000.0 };
CGSize size = [message sizeWithFont:[UIFont boldSystemFontOfSize:13]
constrainedToSize:textSize
lineBreakMode:UILineBreakModeWordWrap];
size.width += (padding/2);
// Left/Right bubble
UIImage *bgImage = nil;
if ([[[DataManager shared] currentUser] ID] == messageBody.senderID || self.currentRoom) {
bgImage = [[UIImage imageNamed:#"orange.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
[cell.message setFrame:CGRectMake(padding, padding*2, size.width+padding, size.height+padding)];
[cell.backgroundImageView setFrame:CGRectMake( cell.message.frame.origin.x - padding/2,
cell.message.frame.origin.y - padding/2,
size.width+padding,
size.height+padding)];
cell.date.textAlignment = UITextAlignmentLeft;
cell.backgroundImageView.image = bgImage;
if(self.currentRoom){
cell.date.text = [NSString stringWithFormat:#"%d %#", messageBody.senderID, time];
}else{
cell.date.text = [NSString stringWithFormat:#"%# %#", [[[DataManager shared] currentUser] login], time];
}
} else {
bgImage = [[UIImage imageNamed:#"aqua.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
[cell.message setFrame:CGRectMake(320 - size.width - padding,
padding*2,
size.width+padding,
size.height+padding)];
[cell.backgroundImageView setFrame:CGRectMake(cell.message.frame.origin.x - padding/2,
cell.message.frame.origin.y - padding/2,
size.width+padding,
size.height+padding)];
cell.date.textAlignment = UITextAlignmentRight;
cell.backgroundImageView.image = bgImage;
cell.date.text = [NSString stringWithFormat:#"%# %#", self.opponent.login, time];
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messages count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
QBChatMessage *chatMessage = (QBChatMessage *)[messages objectAtIndex:indexPath.row];
NSString *text = chatMessage.text;
CGSize textSize = { 260.0, 10000.0 };
CGSize size = [text sizeWithFont:[UIFont boldSystemFontOfSize:13]
constrainedToSize:textSize
lineBreakMode:UILineBreakModeWordWrap];
size.height += padding;
return size.height+padding+5;
}
#pragma mark -
#pragma mark QBChatDelegate
// Did receive 1-1 message
- (void)chatDidReceiveMessage:(QBChatMessage *)message{
[self.messages addObject:message];
// save message to cache if this 1-1 chat
if (self.opponent) {
[[DataManager shared] saveMessage:[NSKeyedArchiver archivedDataWithRootObject:messages]
toHistoryWithOpponentID:self.opponent.ID];
}
// reload table
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
// Did receive message in room
- (void)chatRoomDidReceiveMessage:(QBChatMessage *)message fromRoom:(NSString *)roomName{
// save message
[self.messages addObject:message];
// reload table
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
// Fired when you did leave room
- (void)chatRoomDidLeave:(NSString *)roomName{
NSLog(#"Chat Controller chatRoomDidLeave");
}
// Called in case changing occupant
- (void)chatRoomDidChangeOnlineUsers:(NSArray *)onlineUsers room:(NSString *)roomName{
NSLog(#"chatRoomDidChangeOnlineUsers %#, %#",roomName, onlineUsers);
}
- (void)chatRoomDidEnter:(QBChatRoom *)room{
NSLog(#"Private room %# was created", room.name);
// You have to retain created room if this is temporary room. In other cases room will be destroyed and all occupants will be disconnected from room
self.currentRoom = room;
// Add users to this room
NSInteger user_id = [[[[API sharedInstance] user] objectForKey: #"id"] intValue];
NSNumber *me = [NSNumber numberWithInt: user_id];
NSArray *users = [NSArray arrayWithObjects: me, nil];
[[QBChat instance] addUsers:users toRoom:room];
}
#end
I'm not sure that you have user with these credentials
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"jerry";
I first check user exist or not modified your code like this...
//your code
.....
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
//Create extended session request with user authorization
QBASessionCreationRequest *extendedAuthRequest = [QBASessionCreationRequest request];
//Check user exist or not
if(self.currentQBUser){
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"testjk";
}
[QBAuth createSessionWithExtendedRequest:extendedAuthRequest delegate:self];
}
........
- (void)completedWithResult:(Result *)result{
// Create session result
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// Register new user
self.currentQBUser = [[QBUUser alloc] init];
user.fullName = #"Your Name";
user.login = #"testjk";
user.password = #"testjk";
user.tags = [NSMutableArray arrayWithObject:#"Chat"];
// Create user
[QBUsers signUp:user delegate:self];
// You have successfully created the session
QBAAuthSessionCreationResult *res = (QBAAuthSessionCreationResult *)result;
} else if([result isKindOfClass:[QBUUserLogInResult class]]){
if(result.success){
QBUUserLogInResult *res = (QBUUserLogInResult *)result;
//Now login to chat
// Sign In to QuickBlox Chat
QBUUser *currentUser = res.user;
currentUser.ID = #"testjk; // your current user's ID
currentUser.password = #"testjk"; // same as user id
// set Chat delegate
[QBChat instance].delegate = self;
// login to Chat
[[QBChat instance] loginWithUser:currentUser];
}
}
if (result.errors.count && (401 != result.status))
{
NSLog(#"QBErrors: %#",result.errors);
}
}
I met the same problem here. And i gave the way i made it.
error unauthorized is the user.login or user.password.
user.login can not be email address but your login username. these i do not know why.
user.password is the email address/username password.
check these informations in your User list at QuickBlox Dashboard
Hope these instructions will help.
use quickblox.min.js
var QBApp = {
appId: 123,
authKey: 'dfdgfd44444',
authSecret: 'dffdgfdg455445'
};
$(document).ready(function () {
QB.init(QBApp.appId, QBApp.authKey, QBApp.authSecret);
QB.createSession(function (err, result) {
console.log('Session create callback', err, result);
});
})
function addUser() {
var pwd, ctr, data;
ctr = document.getElementById(myForm.password);
pwd = ctr.value;
var params = { 'login': 'Rajesh', 'password': 'Pass#123' };
alert(params)
QB.users.create(params, function (err, user) {
debugger;
if (user) {
alert('Done')
//$('#output_place').val(JSON.stringify(user));
} else {
alert('Error')
//$('#output_place').val(JSON.stringify(err));
}
})}